/*
模块名称：收款
起始日期：2021-6-23
功能描述：
1、点击“刷新”，提取可收费患者列表。
2、双击列表中患者，提取患者对应收费项目明细，计算合计金额、应缴现金。
3、如需医保结算，点击“医保结算”进行医保卡预结算过程，计算医保结算之后需要支付的现金。
4、输出实付金额，计算找零。
5、点击“收费保存”进行数据存储、发票打印。
6、如发生打印机械故障，可点击“发票打印”，只进行打印，不再进行数据存储。
业务逻辑：
1.

*/
#include "sk_form_sk.h"
#include "ui_sk_form_sk.h"
#include "pub_var.h"
#include <QSettings>
#include <QDebug>
#include <QSqlError>
#include <QMessageBox>
#include <QDateTime>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <QSqlRecord>

#include <QMetaType>

Form_sk::Form_sk(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form_sk)
{
    ui->setupUi(this);

    this->setWindowTitle("收款－当前用户－"+pub::usr_name);     //窗口标题

    QSettings setIni("clin.ini", QSettings::IniFormat);     //配置文件

    QRect rct = setIni.value("windowState/sk").toRect();    //恢复当前窗口位置
    this->setGeometry(rct);

    //数据库连接
    qrm = new QSqlQuery(pub::db_m);
    qrmt = new QSqlQuery(pub::db_m);
    qro = new QSqlQuery(pub::db_o);
    qro2 = new QSqlQuery(pub::db_o);

    if( "1" == setIni.value("sk/autodisplay").toString())
    {
        //自动刷新待收款列表
        ui->cbAutoFlash->setChecked(true);
    }
    else
    {
        ui->cbAutoFlash->setChecked(false);
    }

    QString printerName = setIni.value("sk/printer").toString();    //收款打印机名称

    //配置打印机
    prt= new QPrinter(QPrinter::HighResolution);
    prt->setPrinterName(printerName);

    //发票纸张大小设定
    qrm->exec(" select p_width,p_height from com_printer_setting "
              " where p_type = '门诊收据' and p_item = '页面'");
    int w = 0, h = 0;
    if(qrm->next())
    {
        w = qrm->value(0).toInt();
        h = qrm->value(1).toInt();
    }
    else
    {
        QMessageBox::information(this,"错误","门诊收据打印参数缺失！");
    }

    QSizeF sz = QSizeF(w,h);
    QPageSize psz(sz,QPageSize::Millimeter,"mzsj",QPageSize::FuzzyMatch);
    prt->setPageSize(psz);

    QPageLayout pglot = QPageLayout(prt->pageLayout());
    //QRectF szf = pglot.fullRect(QPageLayout::Point);

    int dotPerInch = prt->physicalDpiX();
    ptScale = double(dotPerInch) / 25.4 ;

    prt->setOrientation(QPrinter::Portrait);      // 纵向打印, Landscape 横向打印
    prt->setFullPage(true);
    pnt = new QPainter();

    QFont ft = this->font(); //当前界面默认字体

    ui->tvBzh->setFont(ft);   //待付款人员列表字体
    ui->tvXmmx->setFont(ft);   //待付款项目明细列表字体

    ft.setBold(true);

    //设置应收金额等字体颜色
    ui->leYjxj->setFont(ft);
    ui->leSf->setFont(ft);
    ui->leZl->setFont(ft);

    ui->leYjxj->setStyleSheet("color: black;");

    //提示信息闪动显示
    tm = new QTimer();
    connect(tm, SIGNAL(timeout()), this, SLOT(onTimerOut()));

    uiInit();//界面控件状态初始设定

    //初始化医保线程
    qDebug()<<"initialYb thread";
    ybBusiness = new ThreadYb(this);
    thread = new QThread();
    ybBusiness->moveToThread(thread);
    qDebug()<<"thread start";
    thread->start();

    //发出信号启动医保交易线程
    connect(this, SIGNAL(opThread(int, QString)),
            ybBusiness, SLOT(doWork(int, QString)),Qt::BlockingQueuedConnection);

    //连接线程返回信号
    connect(ybBusiness, SIGNAL(resultReady(int, QString, QString)),
            this, SLOT(handleRet(int, QString, QString)),Qt::BlockingQueuedConnection);

    //医保访问网络配置
    request.setUrl(QUrl(pub::hos_ybjy));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    request_zjzf.setUrl(QUrl(pub::zj_push_ip));
    request_zjzf.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

}

Form_sk::~Form_sk()
{
    delete ui;
}

void Form_sk::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event);
    QSettings setIni("clin.ini", QSettings::IniFormat);
    setIni.setValue("windowState/sk", QVariant(this->geometry()));

    if(ui->cbAutoFlash->isChecked())
    {
        setIni.setValue("sk/autodisplay", 1);
    }
    else
    {
        setIni.setValue("sk/autodisplay", 0);
    }
    emit destroyW( "form_sk" );
}

void Form_sk::onTimerOut()
{
    //刷新提示信息
    if( ui->lbMode->text().isEmpty())
    {
        ui->lbMode->setText(statusMsg);
    }
    else
    {
        ui->lbMode->setText("");
    }
    qApp->processEvents();
}

void Form_sk::handleRet(const int r, const QString o1,const QString o2)
{
    qDebug()<<"recive signal from ybThread ...";
    businessRetVal = r;
    businessRetStr1 = o1;
    businessRetStr2 = o2;
    businessFinish = true;
}

void Form_sk::resizeEvent(QResizeEvent *event)
{

    Q_UNUSED(event);
    
    //窗口界面大小变化，重新设定列表显示内容
    pub::setColumnWidth(ui->tvBzh, "0.33^0.33^0.33", ui->tvBzh->width() -50, 16);

    pub::setColumnWidth(ui->tvXmmx, "0.35^0.25^0.1^0.1^0.2", ui->tvXmmx->width() -50, 12);

}

void Form_sk::on_pbTc_clicked()
{
    this->close();
}

void Form_sk::on_pbSx_clicked()
{

    qDebug()<<"on_pbSx_clicked()\n";
    //数据提取期间，刷新按钮暂时禁用
    ui->pbSx->setEnabled(false);
    
    ui->leBzh->setText("");
    ui->leSf->setText("");
    ui->leYjxj->setStyleSheet("color: black;");
    ui->leZl->setText("");
    ui->pbSfbc->setEnabled(false); //
    ui->pbYbjs->setEnabled(false); //
    need_process_5465 = false;
    ui->rbX->setChecked(true);      //现金
    ui->rbX->setEnabled(false);      //
    ui->rbK->setEnabled(false);      //
    ui->rbM->setEnabled(false);      //
    ui->rbZ->setEnabled(false);      //
    mdXmmx.setQuery(NULL);          //项目明细列表清空
    qApp->processEvents();  //刷新显示
    //刷新可收费患者列表

    sq = "select distinct f.card_no, r.name, r.dept_name, r.dept_code, " //0-3
         " f.clinic_code, to_char(r.reg_date, 'yyyy-mm-dd hh24:mi:ss')reg_dt,"//4-5
         "r.PAYKIND_CODE, r.PACT_CODE, r.PACT_NAME, r.MCARD_NO, r.MEDICAL_TYPE, "//6-10
         "to_char(r.birthday,'yyyy-mm-dd'), r.sex_code, r.idenno, "//11-13
         " r.card_type, r.rela_phone "//14-15
         " from met_ord_recipedetail f, fin_opr_register r "
         " where r.reg_date + 3 > trunc(sysdate)  "//三天内未收费数据
         " and f.clinic_code = r.clinic_code and f.charge_flag = '0'"
         " and f.status <> '4' and r.valid_flag = '1' ";

    sq = sq + " order by reg_dt desc";

    qDebug()<<"提取待收费患者列表: "<<sq<<"\n";

    mdBzh.setQuery(sq, pub::db_o);
    mdBzh.setHeaderData(0, Qt::Horizontal, "门诊号");
    mdBzh.setHeaderData(1, Qt::Horizontal, "姓名");
    mdBzh.setHeaderData(2, Qt::Horizontal, "诊室");
    ui->tvBzh->setModel(&mdBzh);
    pub::setColumnWidth(ui->tvBzh, "0.33^0.33^0.33", ui->tvBzh->width() -50, 16);
    
    //恢复刷新按钮
    ui->pbSx->setEnabled(true);
}

void Form_sk::on_tvBzh_doubleClicked(const QModelIndex &index)
{
    qDebug()<<"提取待收费患者个人信息\n";
    ui->pbPrint->setEnabled(false); //打印
    //提取被选中患者的相关信息

    patientInfo.clear();
    patientInfo["PATIENT_NAME"] = index.siblingAtColumn(1).data(0).toString();
    patientInfo["CLINIC_CODE"] = index.siblingAtColumn(4).data(0).toString();
    patientInfo["CARD_NO"] = index.siblingAtColumn(0).data(0).toString();
    patientInfo["regDeptCode"] = index.siblingAtColumn(3).data(0).toString();
    patientInfo["REG_DATE"] = index.siblingAtColumn(5).data(0).toString();
    patientInfo["MCARD_NO"] = index.siblingAtColumn(9).data(0).toString();
    patientInfo["MEDICAL_TYPE"] = index.siblingAtColumn(10).data(0).toString();
    patientInfo["BIRTHDAY"] = index.siblingAtColumn(11).data(0).toString();
    patientInfo["SEX_CODE"] = index.siblingAtColumn(12).data(0).toString();
    patientInfo["IDENNO"] = index.siblingAtColumn(13).data(0).toString();
    patientInfo["CARD_TYPE"] = index.siblingAtColumn(14).data(0).toString();
    patientInfo["PHONE"] = index.siblingAtColumn(15).data(0).toString();

    ui->leBzh->setText(patientInfo["CARD_NO"] + "，" + patientInfo["PATIENT_NAME"] + "，"+
            index.siblingAtColumn(3).data(0).toString());

    qDebug()<<"患者姓名, 病志号： "<<patientInfo["PATIENT_NAME"]
           <<" , "<<patientInfo["CARD_NO"]<<"\n";

    //支付模式默认为现金，检测环境允许之后设置医保结算按钮有效，进行医保预结算成功之后，收费模式改为医保
    //ui->lbMode->setText("收费方式：现金 、POS机");
    ui->rbX->setChecked(true);
    if( "02" == index.siblingAtColumn(6).data(0).toString() && pub::useInsurance )
    {
        //医保挂号，且医保环境有效
        ui->pbYbjs->setEnabled(true);
        need_process_5465 = true;
    }
    else
    {
        ui->pbYbjs->setEnabled(false);  //设置医保结算按钮无效
        need_process_5465 = false;
    }

    patientInfo["yb"] = "0";  //医保交易标志， 0未交易，1已交易

    patientInfo["PAYKIND_CODE"] = "01";//
    patientInfo["PACT_CODE"] = "1";//index.siblingAtColumn(7).data(0).toString();
    patientInfo["PACT_NAME"] = "现金";//index.siblingAtColumn(8).data(0).toString();
    patientInfo["currentInvoNo"] = "";//当前发票号预置为空，正式结算时填入实际发票号
    patientInfo["ybToken"] = "";//令牌
    patientInfo["ybMode"] = ""; //医保模式，card, code, id

    recipe_list_5465.clear();
    on_leBzh_returnPressed();

}

void Form_sk::on_leBzh_returnPressed()
{
    nonInsuItem = false;    //出现非医保项目
    hasInsuItem = false;    //待结算数据中包含医保项目
    nonInsuAmount = 0;  //非医保金额
    //项目明细列表
    sq = "select item_name, specs,  qty lst_qty , item_unit price_unit, own_cost," //0-4
         " sequence_no mo_order, item_code, unit_price /pack_qty  unit_price, "//5-7
         " doct_code, doct_dpcd doct_dept, qty * pack_qty rqty , pack_qty, comb_no, "//8-12
         " exec_dpcd ,recipe_no"//13-14
         " from met_ord_recipedetail "
         " where clinic_code = '" + patientInfo["CLINIC_CODE"];
    sq += "' and status <> '4' and charge_flag <>'1' order by recipe_no, sequence_no ";

    qDebug()<<"提取收费项目明细： "<<sq;
    mdXmmx.setQuery(sq, pub::db_o);

    if(mdXmmx.rowCount() == 0)
    {
        //对应患者无收费明细，返回
        qDebug()<<"对应患者无收费明细\n";
        return;
    }

    mdXmmx.setHeaderData(0, Qt::Horizontal, "项目名称");
    mdXmmx.setHeaderData(1, Qt::Horizontal, "规格");
    mdXmmx.setHeaderData(2, Qt::Horizontal, "数量");
    mdXmmx.setHeaderData(3, Qt::Horizontal, "单位");
    mdXmmx.setHeaderData(4, Qt::Horizontal, "金额");

    ui->tvXmmx->setModel(&mdXmmx);

    pub::setColumnWidth(ui->tvXmmx, "0.35^0.25^0.1^0.1^0.2^0^0^0^0^0^0^0^0^0^0^0",
                        ui->tvXmmx->width() -50, 15);

    //计算合计金额
    mdXmmx.query().first();
    double hjje = mdXmmx.query().value(4).toDouble();

    while(mdXmmx.query().next())
    {
        hjje = hjje + mdXmmx.query().value(4).toDouble();
    }

    ui->leHjje->setText(QString::asprintf("%.2f",hjje));
    ui->leYjxj->setText(ui->leHjje->text());
    ui->leZhzf->setText("0");       //账户
    ui->leTczf->setText("0");       //基金支付
    ui->leGjzf->setText("0");       //共济
    ui->leSf->setText(ui->leYjxj->text());

    qDebug()<<"待收费金额："<<ui->leHjje->text()<<"\n";

    //设置收费结算按钮可用
    //ui->pbSfbc->setEnabled(true);

    //提取数据到 lstItemDetail
    sq = "select f.doct_dpcd,f.exec_dpcd,f.drug_quanlity,f.specs,f.item_unit," //0-4
         "f.pack_qty,f.qty * f.pack_qty,f.days,f.clinic_code,f.DEPT_CODE,"//5-9
         "f.once_dose,f.once_unit,f.usage_code,f.usage_name, "//10-13
         "f.dose_model_code,f.sequence_no,f.comb_no,f.recipe_no,"//14-17
         "f.recipe_seq,f.frequency_code,"//18-19
         "b.DRUG_TYPE,b.MIN_UNIT,b.RETAIL_PRICE,b.Drug_Code,"//20-23
         "B.TRADE_NAME, drug_flag , f.own_cost, f.doct_code, exec_dpcd,"//24-28  drug_flag '1'
         " f.doct_name,"//29
         "(select c.si_code from COM_DOCTOR_COMPARE c "
         "    where rownum = 1 and c.empl_code=f.doct_code and c.valied_state='1'),"//30
         "to_char(f.oper_date,'yyyymmddhh24miss')  , "
         " phamarcy_code,FREQUENCY_NAME, b.split_type, "//31-34
         " b.id_code, b.id_code_count "//35-36
         " from "
         " met_ord_recipedetail f, pha_com_baseinfo b "
         " where "
         " f.item_code = b.drug_code and f.charge_flag ='0' and f.status <> '4' "
         " and f.drug_flag in('1','4') and f.clinic_code = '" + patientInfo["CLINIC_CODE"] + "' ";
     sq += "union " // 药品 union 非药品
         "select f.doct_dpcd,f.exec_dpcd,f.drug_quanlity,f.specs,f.item_unit,"//0-4
           "f.pack_qty,f.qty,f.days,f.clinic_code,f.dept_code,"//5-9
           "f.once_dose,f.once_unit,f.usage_code,f.usage_name, "//10-13
           "f.dose_model_code,f.sequence_no,f.comb_no,f.recipe_no,"//14-17
           "f.recipe_seq,f.frequency_code, "//18-19
           "'','',f.unit_price,f.item_code,"//20-23
           "f.item_name, drug_flag , f.own_cost, f.doct_code, exec_dpcd,"//24-28  drug_flag '2'
         " f.doct_name,"//29
         "(select c.si_code from COM_DOCTOR_COMPARE c "
         "     where rownum = 1 and c.empl_code=f.doct_code and c.valied_state='1'), "//30
         " to_char(f.oper_date,'yyyymmddhh24miss') , "
         " phamarcy_code,FREQUENCY_NAME,'','',0 "//31-36
         " from "
         " met_ord_recipedetail f "
         " where "
         " f.charge_flag = '0' and f.status <> '4' "
         " and f.drug_flag not in('1','4') and f.clinic_code = '" + patientInfo["CLINIC_CODE"] + "' "
         "order by recipe_no";

    qDebug()<<"提取数据到 lstItemDetail "<<sq;

    if(!qro->exec(sq))
    {
        QMessageBox::information(this,"注意", " 提取数据失败！"+qro->lastError().text() );
        qDebug()<<qro->lastQuery();
        return;
    }

    QMap<QString, QString> mp;
    lstItemDetail.clear();
    QStringList reci_lst;//检查是否有需要审批的处方

    while(qro->next())
    {
        reci_lst << qro->value(17).toString();

        mp["doct_dept"] = qro->value(0).toString();
        mp["DRUG_DEPT_CODE"] = qro->value(1).toString();
        mp["DRUG_QUALITY"] = qro->value(2).toString();
        mp["SPECS"] = qro->value(3).toString();
        mp["PACK_UNIT"] = qro->value(4).toString();
        mp["PACK_QTY"] = qro->value(5).toString();
        mp["APPLY_NUM"] = qro->value(6).toString();
        mp["DAYS"] = qro->value(7).toString();
        mp["PATIENT_ID"] = qro->value(8).toString();
        mp["PATIENT_DEPT"] = qro->value(9).toString();
        mp["DOSE_ONCE"] = qro->value(10).toString();
        mp["DOSE_UNIT"] = qro->value(11).toString();
        mp["USAGE_CODE"] = qro->value(12).toString();
        mp["USE_NAME"] = qro->value(13).toString();
        mp["DOSE_MODEL_CODE"] = qro->value(14).toString();
        mp["MO_ORDER"] = qro->value(15).toString();
        mp["COMB_NO"] = qro->value(16).toString();
        mp["RECIPE_NO"] = qro->value(17).toString();
        recipe_list_5465 <<qro->value(17).toString();
        mp["SEQUENCE_NO"] = qro->value(18).toString();
        mp["DFQ_FREQ"] = qro->value(19).toString();
        mp["DRUG_TYPE"] = qro->value(20).toString();
        mp["MIN_UNIT"] = qro->value(21).toString();

        QString prc = QString::asprintf("%.6f",qro->value(22).toDouble());
        mp["RETAIL_PRICE"] = pub::remove_trailing_zeros(prc);

        mp["item_code"] = qro->value(23).toString();
        mp["TRADE_NAME"] = qro->value(24).toString();
        mp["drug_flag"] = qro->value(25).toString();
        mp["own_cost"] = qro->value(26).toString();
        mp["doct_code"] = qro->value(27).toString();
        mp["DEPT_CODE"] = qro->value(9).toString();

        mp["doct_name"] = qro->value(29).toString();

        mp["doct_si_code"] = qro->value(30).toString();
        mp["oper_date"] = qro->value(31).toString();
        mp["phamarcy_code"] = qro->value(32).toString();
        mp["freq_name"] = qro->value(33).toString();

        mp["split_type"] = qro->value(34).toString();
        mp["id_code"] = qro->value(35).toString();
        mp["id_code_count"] = qro->value(36).toString();

        //按非医保项目预置内容
        mp["center_code"] = "";
        mp["center_item_grade"] = "";
        mp["center_rate"] = "";
        mp["has_compare"] = "0";
        mp["med_chrgitm_type"] = "";
        //nonInsuItem = true;    //出现非医保项目

        //检查是否存在医保对照目录
        sq = " select med_list_codg,center_item_grade,center_rate,med_chrgitm_type "
             " from fin_com_compare "
             " where fixmedins_hilist_id = '"
                + mp["item_code"] + "' and compare_flag = '0' ";

        qDebug()<<"检查是否存在医保对照目录 : "<<sq;

        if(!qro2->exec(sq))
        {
            QMessageBox::information(this,"注意", "读取 fin_com_compare 失败！"+qro2->lastError().text() );
            return;
        }

        if(qro2->next())
        {
            mp["center_code"] = qro2->value(0).toString();
            mp["center_item_grade"] = qro2->value(1).toString();
            mp["center_rate"] = qro2->value(2).toString();
            mp["has_compare"] = "1";
            mp["med_chrgitm_type"] = qro2->value(3).toString();
            hasInsuItem = true;
        }
        else
        {
            QMessageBox::information(this,"注意", "未查询到 " + mp["item_code"]
                    + "/"+mp["TRADE_NAME"]+" 的医保对照记录，只能按现金收费！");
            //return;
        }

        //检查是否存在医保挂号，现金开药
        sq = "select mo_order from fin_opb_insu_cash where mo_order = '"
                + mp["MO_ORDER"] + "'";
        qDebug()<<"检查是否存在医保挂号，现金开药 : "<<sq;
        qro2->exec(sq);

        if(qro2->next())
        {
            mp["has_compare"] = "0";
        }

        lstItemDetail << mp;
        qDebug()<<"收费明细项目："<<mp;
    }

    qDebug()<<"lstItemDetail : "<<lstItemDetail<<"\n";

    mp.clear();

    ui->pbSfbc->setEnabled(true);

    qDebug()<<"提取患者收费明细结束。\n";

}

void Form_sk::on_leSf_textChanged(const QString &arg1)
{
    if(arg1.isEmpty())
    {
        return;
    }

    //计算现金找零
    double yj, sf, zl;
    yj = ui->leYjxj->text().toDouble(); //实际应交金额
    sf = ui->leSf->text().toDouble(); //实际支付金额

    //2025-01-09 修改
    double yj45 = QString::asprintf("%.1f", yj).toDouble(); //四舍五入应交金额

    //if(qFuzzyCompare(yj, sf))
    if( qFuzzyCompare(yj, sf) || qFuzzyCompare(yj45, sf) )
    {
        //直接相等，或四舍五入后相等
        zl = 0;
    }
    else if(sf > yj)
    {
        zl = sf - yj ;
    }
    else
    {
        //QMessageBox::information(this,"错误","实付款不能小于应付款！");
        ui->pbSfbc->setEnabled(false);
        return;
    }

    ui->pbSfbc->setEnabled(true);
    ui->leZl->setText(QString::asprintf("%.1f",zl));

}

void Form_sk::on_rbX_clicked()
{
    patientInfo["ybMode"] = "";
    patientInfo["yb"] = "0";
}

void Form_sk::on_rbK_clicked()
{
    patientInfo["ybMode"] = "card";
}

void Form_sk::on_rbM_clicked()
{
    patientInfo["ybMode"] = "code";
}

void Form_sk::on_rbZ_clicked()
{
    patientInfo["ybMode"] = "id" ;
}

QString Form_sk::getDoctCode(QString s)
{
    //检索发票关联的医生
    QString ret = "";
    QMap<QString,QString>m;
    QStringList retList;
    foreach(m, lstItemDetail)
    {
        if(m["invoice_no"] == s)
        {
            retList << m["doct_code"];
        }
    }
    retList.removeDuplicates();
    foreach(QString s, retList)
    {
        if(ret.isEmpty())
        {  //
            ret = s;
        }
        else
        {
            ret = ret + "," + s ;
        }

    }
    return ret;
}

QStringList Form_sk::getFeeTypes(QString s)
{
    //检索发票关联的费别
    QStringList ret ;
    QMap<QString,QString>m;
    foreach(m, lstFeeType)
    {
        if(m["invoice_no"] == s)
        {
            ret << m["fee_name"] + " : " + m["own_cost"];
        }
    }

    return ret;
}

QStringList Form_sk::getItems(QString s)
{
    //检索发票关联的项目明细
    QStringList ret ;
    QMap<QString,QString>m;
    foreach(m, lstItemDetail)
    {
        if(m["invoice_no"] == s)
        {
            QString grd = m["center_item_grade"] ;
            if(grd == "01")
            {
                grd = "(甲)";
            }
            else if (grd == "02")
            {
                grd = "(乙)";
            }
            else if (grd == "03")
            {
                grd = "(丙)";
            }
            else
            {
                grd = "";
            }
            ret << grd + m["TRADE_NAME"] + "^"
                    + m["SPECS"] + "^" +
                    QString::number(m["APPLY_NUM"].toInt() / m["PACK_QTY"].toInt())
                    + "^" + m["RETAIL_PRICE"];
        }
    }
    return ret;
}

QString Form_sk::getInvoiceNo(QString s)
{
    //检索科室关联的发票号
    QString ret = "";
    QMap<QString,QString>m;

    foreach(m, lstInvoiceInfo)
    {
        if(m["dept_code"] == s)
        {
            return m["invoice_no"] + "^" + m["invoice_seq"];
        }
    }
    return ret;
}

void Form_sk::on_pbYbjs_clicked()   //医保预结算
{

    ui->pbYbjs->setEnabled(false);//正常情况下，预结算只需要操作一次

    if(!hasInsuItem)
    {
        QMessageBox::information(this,"note","列表中没有医保项目，无法使用医保结算。");
        return;
    }

    //预置医保结算失败之后的状态。如果医保预结算成功，此状态会被修改
    ui->pbSfbc->setEnabled(false);  //医保预结算期间禁止操作

    qApp->processEvents();
    ui->lbMode->setText("收费方式：现金 、POS机");
    patientInfo["PAYKIND_CODE"] = "01";
    patientInfo["PACT_CODE"] = "1";
    patientInfo["PACT_NAME"] = "现金";
    ui->rbX->setChecked(true);
    tm->start(500);

    if(ybyjs())
    {
        QMessageBox::information(this,"note","预结算成功！");
        if(mdtrt_cert_type == "03")
        {
            //医保模式
            ui->lbMode->setText("收费方式：沈阳市医保，刷卡支付");
        }
        else if(mdtrt_cert_type == "01")
        {
            ui->lbMode->setText("收费方式：沈阳市医保，电子医保二维码");
        }
        else if(mdtrt_cert_type == "02")
        {
            ui->lbMode->setText("收费方式：沈阳市医保，身份证方式");
        }
    }
    else
    {
        ui->pbYbjs->setEnabled(true);//预结算不成功，可以再次尝试
    }
    ui->pbSfbc->setEnabled(true);  //医保预结算结束
    //
    tm->stop();
}

bool Form_sk::ybyjs()
{
    //医保信息住院主表，查询当前流水号，检查是否使用医保挂号

    qDebug()<<"医保预结算开始。。。\n";

    statusMsg = "检索基础数据。。。";

    if(!searchBaseData()){
        return false;
    }

    statusMsg = "医保状态有效性验证。。。";

    //卡机开始读卡
    int mod = mdtrt_cert_type.toInt();

    QJsonDocument d;    //清空QJsonObject之用
    QJsonObject in; //入参
    QJsonObject inpu,inpud; // 入参 input 段
    QJsonDocument indoc;

    QString sfzh;//身份证号
    qDebug()<<"mod"<<mod;

    if(mod == 1)
    {

        if(!scanCode())
        {
            return false;
        }

        inpu.insert("mdtrt_cert_type", mdtrt_cert_type);   //就诊凭证类别
        inpu.insert("mdtrt_cert_no", retScan.value("ecToken").toString());   //token
        inpu.insert("psn_name", retScan.value("userName").toString()); //人员姓名
        //inpu.insert("card_sn", retScan.value("ecToken").toString()); //卡识别码
        inpu.insert("certno", retScan.value("idNo").toString() );      //证件号码
        inpu.insert("psn_cert_type","01");       //人员证件类型  固定？
        //        sfzh = retScan.value("idNo").toString();

    }
    else if(mod == 2)
    {
        if(!readIdCard())
        {
            return false;
        }
        inpu.insert("mdtrt_cert_type", mdtrt_cert_type);   //就诊凭证类别
        inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",2) + "|" + busiCardInfo);   //社保卡,4卡号3社保号
        inpu.insert("psn_name", pub::getStr(cardInfo,"|",5)); //人员姓名
        inpu.insert("certno", pub::getStr(cardInfo,"|",2));      //证件号码
        inpu.insert("psn_cert_type","01");       //人员证件类型  固定？
         sfzh = pub::getStr(cardInfo,"|",2);

    }
    else if(mod == 3)
    {
        if(!readCard())
        {
            return false;
        }
        //emit opThread( mod , "QString");    // 发送信号触发线程 , 执行 ReadCardBas
        inpu.insert("mdtrt_cert_type", mdtrt_cert_type);   //就诊凭证类别
        if( "1" == pub::getStr(cardInfo,"|",1) ){   //0 社保卡， 1 老医保卡
            if(pub::getStr(cardInfo,"|",8).isEmpty()){
                inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",9) + "|" + busiCardInfo);//老医保卡,8卡号9社保号
            }else{
                inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",8) + "|" + busiCardInfo);//老医保卡,8卡号9社保号
            }
            //sfzh = pub::getStr(cardInfo,"|",9);
            inpu.insert("psn_name", pub::getStr(cardInfo,"|",10)); //人员姓名
            inpu.insert("card_sn",pub::getStr(cardInfo,"|",2)); //卡识别码
            inpu.insert("certno", pub::getStr(cardInfo,"|",9));      //证件号码
            inpu.insert("psn_cert_type","01");       //人员证件类型  固定？
        }else{
            inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",4) + "|" + busiCardInfo);   //社保卡,4卡号3社保号
            inpu.insert("psn_name", pub::getStr(cardInfo,"|",6)); //人员姓名
            inpu.insert("card_sn",pub::getStr(cardInfo,"|",5)); //卡识别码
            inpu.insert("certno", pub::getStr(cardInfo,"|",3));      //证件号码
            inpu.insert("psn_cert_type","01");       //人员证件类型  固定？
            //sfzh = pub::getStr(cardInfo,"|",3);
        }
    }

    qDebug()<< " 1100 获取人员信息\n";
    statusMsg = "1100 获取人员信息。。。";
    //1100开始获取人员信息
    in = d.object();

    if(!putBaseIn(  in, "1101"))
    {
        return false;
    }

    inpud.insert("data",inpu);
    in.insert("input", inpud);
    indoc.setObject(in);

    //保存入参日志
    sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }

    QNetworkReply* reply = manager.post(request,indoc.toJson());
    QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " http 请求状态错误: " + statusCode.toString());
        return false ;
    }

    QNetworkReply::NetworkError err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false ;
    }

    QByteArray btret = reply->readAll();
    QString t = QString::fromLocal8Bit(btret);

    QJsonParseError json_error;

    QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);

    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 返回信息解析错误 " + json_error.errorString());
        return false ;
    }

    QJsonObject jsob = jsdc.object();

    //保存出出参日志
    QString out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set tmstmp = now(), v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +  "  where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }

    if(jsob.value("infcode").toInt() != 0)
    {
        QString t = jsob.value("err_msg").toString();
        QMessageBox::warning(NULL,"注意", currentInfno + " 交易失败：" + t );
        return false ;
    }

    personBaseinfo = jsob.value("output").toObject().value("baseinfo").toObject();
    //personInsuinfo = jsob.value("output").toObject().value("insuinfo")[0].toObject();

    //读卡返回的个人险种排序无规律，需要人工查找指定的险种
    personInsuinfoA = jsob.value("output").toObject().value("insuinfo").toArray();
    QString insutype;
    bool found = false;

    for(int a = 0; a< personInsuinfoA.size(); a++)
    {
        insutype = personInsuinfoA[a].toObject().value("insutype").toString();
        if(personInsuinfoA[a].toObject().value("psn_insu_stas").toString() != "1")
        {
            //非有效参保状态
            continue;
        }
        //如果发现职工医保或居民医保，保存，退出循环
        qrmt->exec("select name from com_dict_com where dic_type = '险种' and code = '"+insutype+"'");
        if(qrmt->next())
        {

            if( insutype == "310" )
            {
                otp_mulaid_used_flag_0 = pub::otp_mulaid_used_flag;
            }
            else
            {
                otp_mulaid_used_flag_0 = "0";
            }
            //pub::current_insu_type = insutype;
            personInsuinfo = personInsuinfoA[a].toObject();
            found = true;
            //ui->rbY->setText(qrmt->value(0).toString());
            break;
        }
    }

    //如果未发现有效险种，读取第一个险种
    if(!found)
    {
        personInsuinfo = jsob.value("output").toObject().value("insuinfo")[0].toObject();
    }

    personIdetinfo = jsob.value("output").toObject().value("idetinfo")[0].toObject();

    qDebug()<< " 1100 结束，开始2203A\n";

    statusMsg = "2203 就诊信息上传。。。";

    inpu = d.object();
    inpud = d.object();
    in = d.object();

    if(!putBaseIn( in, "2203A"))
    {
        return false;
    }

    inpu.insert("mdtrt_id", patientInfo["mdtrt_id"]);   //就诊ID
    inpu.insert("psn_no", personBaseinfo.value("psn_no").toString());   //人员编号
    //inpu.insert("med_type","110104");//	医疗类别 110104 门诊统筹， 11 普通门诊， 12 挂号
    inpu.insert("med_type","11");//	医疗类别 110104 门诊统筹， 11 普通门诊， 12 挂号
    inpu.insert("begntime", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));//	开始时间

    QJsonObject t2203exp;

    t2203exp.insert("trum_flag","0");  //   外伤标志
    t2203exp.insert("rel_ttp_flag","0");    //涉及第三方标志
    t2203exp.insert("otp_mulaid_used_flag", otp_mulaid_used_flag_0); //共济标志，  0共济，1不共济。
    //t.insert("mdtrt_grp_type","0");  //就诊人群类型
    //t.insert("elec_bill_code","0");  //电子票据代码
    //t.insert("elec_billno_code","0"); //电子票据号码
    //t.insert("otp_er_refl_flag","0");    //门诊急诊转诊标志

    inpu.insert("exp_content", t2203exp);//	字段扩展
    inpud.insert("mdtrtinfo",inpu);

    inpu = d.object();      //临时变量清空

    QJsonArray djsar;//诊断

    QMap<QString, QString> mp;
    int i = 0;

    foreach(mp, diag)
    {
        i ++;
        //qDebug()<<"mp"<<mp["deptName"]<<mp["diag_code"]<<mp["diag_name"];
        inpu.insert("diag_type", "1");   //诊断类别：1 西医主要诊断， 2 中医主病诊断	3 中医主证诊断
        inpu.insert("diag_srt_no", i );   //诊断排序号
        inpu.insert("diag_code", mp["diagCode"]); //诊断代码
        inpu.insert("diag_name", mp["diagName"]);//诊断名称
        qro->exec("select dept_name from com_department where dept_code='"+mp["deptCode"]+"'");
        qro->next();
        inpu.insert("diag_dept", qro->value(0).toString());   //诊断科室
        inpu.insert("dise_dor_no", mp["doctCode"]);   //诊断医生编码
        inpu.insert("dise_dor_name", mp["doctName"]);//诊断医生姓名
        inpu.insert("diag_time", mp["operDate"]);//诊断时间
        inpu.insert("vali_flag", "1");//有效标志
        djsar<<inpu;
    }

    inpud.insert("diseinfo", djsar);
    in.insert("input", inpud);
    indoc.setObject(in);
    qDebug()<< currentInfno + " indoc"<<indoc;

    indoc.setObject(in);

    //保存入参日志

    sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq)){
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }

    reply = manager.post(request,indoc.toJson());

    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " http 请求状态错误: " + statusCode.toString());
        return false ;
    }

    err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false ;
    }

    btret = reply->readAll();
    t = QString::fromLocal8Bit(btret);

    jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 返回信息解析错误 " + json_error.errorString());
        return false ;
    }

    jsob = jsdc.object();

    //保存出出参日志

    out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set tmstmp = now(),  v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +  "  where jyls = '"
            + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }

    if(jsob.value("infcode").toInt() != 0)
    {
        QString t = jsob.value("err_msg").toString();
        QMessageBox::warning(NULL,"注意", currentInfno + " 交易失败：" + t );
        return false ;
    }

    qDebug()<< " 2203 结束， 开始 2205\n";
    statusMsg = "2205 撤销无效上传数据。。。";
    //2205,撤销费用明细上传
    //防止多次点击预结算上传重复数据，每次预结之前执行一次清理

    inpu = d.object();
    inpud = d.object();
    in = d.object();

    if(!putBaseIn(  in, "2205"))
    {
        return false;
    }

    inpu.insert("mdtrt_id", patientInfo["mdtrt_id"]);   //就诊ID
    inpu.insert("chrg_bchno", "0000");   //批咨与传“0000”，删除所有未结算数据
    inpu.insert("psn_no", personBaseinfo.value("psn_no").toString());//
    inpud.insert("data",inpu);
    in.insert("input", inpud);

    indoc.setObject(in);

    //保存入参日志
    sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }

    reply = manager.post(request,indoc.toJson());

    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        qDebug()<< " 2205请求hhtp状态错误\n";
        QMessageBox::warning(NULL,"注意", currentInfno + " http 请求状态错误: " + statusCode.toString());
        return false ;
    }

    err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false ;
    }

    btret = reply->readAll();
    t = QString::fromLocal8Bit(btret);

    jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 返回信息解析错误 " + json_error.errorString());
        return false ;
    }

    jsob = jsdc.object();

    //保存出出参日志
    out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set tmstmp = now(),   v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +  "  where jyls = '"
            + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }

    //2205 结束
    qDebug()<< " 2205 结束， 开始2204上传费用明细\n";
    statusMsg = "2204 上传费用明细。。。";
    //2204,费用明细上传

    in = d.object();
    inpu = d.object();
    inpud = d.object();
    //putBaseIn(  in, "2204");
    if(!putBaseIn( in, "2204"))
    {
        return false;
    }
    QJsonArray jsar;
    qro->exec("select seq_ftp_seq.nextval from dual");
    qro->next();
    chrg_bchno = qro->value(0).toString();

    qDebug()<< "整理费用明细列表\n";
    for(int i = 0; i< mdXmmx.rowCount(); i++ )
    {
        //收费明细列表
        QString itm = mdXmmx.record(i).value("mo_order").toString();
        //qDebug()<<"mdXmmx.record(i).value(mo_order).toString() is : "<<itm;
        bool compared = false;
        mp.clear();

        //检索品种是否属于医保目录
        foreach(mp, lstItemDetail)
        {
            if(mp["MO_ORDER"] == itm)
            {
                if(mp["has_compare"] == "1")
                {
                    compared = true;
                }
                break;
            }
        }

        if(!compared)
        {
            nonInsuAmount += mdXmmx.record(i).value("own_cost").toDouble();
            continue;
        }

        inpu.insert("feedetl_sn", mdXmmx.record(i).value("MO_ORDER").toString());//	费用明细流水号
        //inpu.insert("feedetl_sn", mp["MO_ORDER"]);
        inpu.insert("mdtrt_id", patientInfo["mdtrt_id"]);//	就诊ID
        inpu.insert("psn_no", personBaseinfo.value("psn_no").toString());//	人员编号
        inpu.insert("chrg_bchno", chrg_bchno);//	收费批次号
        //inpu.insert("rxno", personBaseinfo.value("psn_no").toString());//	处方号
        inpu.insert("rx_circ_flag", "0");//	外购处方标志
        inpu.insert("fee_ocur_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));//	费用发生时间

        QMap<QString, QString> mmp;
        foreach(mmp, lstItemDetail)
        {
            if( mmp["item_code"] == mdXmmx.record(i).value("item_code").toString())
            {
                break;   //
            }
        }

        inpu.insert("med_list_codg", mmp["center_code"]);//	医疗目录编码-00110200001000003

        inpu.insert("medins_list_codg", mdXmmx.record(i).value("item_code").toString());//	医药机构目录编码
        inpu.insert("det_item_fee_sumamt", QString::number(mdXmmx.record(i).value("own_cost").toDouble(),'f',2));//	明细项目费用总额

        inpu.insert("cnt", mdXmmx.record(i).value("rqty").toInt());//	数量
        inpu.insert("pric", QString::number(mdXmmx.record(i).value("unit_price").toDouble(),'f',6));//	单价
        //mp["RETAIL_PRICE"].toDouble() / mp["PACK_QTY"].toDouble() )//	单价
        inpu.insert("bilg_dept_codg", mdXmmx.record(i).value("doct_dept").toString());//	开单科室编码
        qro->exec("select dept_name from com_department where dept_code = '"
                  + mdXmmx.record(i).value("doct_dept").toString() + "'");
        qro->next();

        inpu.insert("bilg_dept_name", qro->value(0).toString());//	开单科室名称

        qro->exec("select si_code, empl_name from com_doctor_compare where empl_code = '"
                  + mdXmmx.record(i).value("doct_code").toString() + "'");
        qro->next();
        inpu.insert("bilg_dr_codg", qro->value(0).toString());//	开单医生编码
        inpu.insert("bilg_dr_name", qro->value(1).toString());//	开单医师姓名
        inpu.insert("hosp_appr_flag", "1");//	医院审批标志

        QString exec_dpcd = mdXmmx.record(i).value("exec_dpcd").toString();//执行科室

        QString tmp_sql ;


        tmp_sql = " select si_code, empl_name "
                  " from com_loginlog "
                  " where login_date > trunc(sysdate) "
                  " and logout_date is null and "
                  " dept_code = '"
                + exec_dpcd + "' order by login_date desc";

        qro->exec(tmp_sql);
        qro->next();

        if(!qro->value(0).toString().isEmpty())
        {
            inpu.insert("orders_dr_code", qro->value(0).toString());//审方药师编码
            inpu.insert("orders_dr_name", qro->value(1).toString());//审方药师姓名
        }

        jsar.append(inpu);

    }

    if(jsar.size() == 0)
    {
        QMessageBox::warning(NULL,"注意"," 项目列表中没有需要医保收费的项目！ " );
        return false ;
    }

    inpud.insert("feedetail", jsar);
    in.insert("input", inpud);
    indoc.setObject(in);

    indoc.setObject(in);

    //保存入参日志
    qDebug()<< currentInfno + " indoc"<<indoc;
    sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq)){
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }

    reply = manager.post(request,indoc.toJson());

    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    qDebug()<<" request " + currentInfno + " is returned ";

    statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " http 请求状态错误: " + statusCode.toString());
        return false ;
    }

    err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false ;
    }

    btret = reply->readAll();
    t = QString::fromLocal8Bit(btret);

    jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 返回信息解析错误 " + json_error.errorString());

        return false ;
    }
    qDebug()<< currentInfno + " outDoc "<<jsdc;
    jsob = jsdc.object();

    //保存出出参日志
    out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set tmstmp = now(),   v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +  "  where jyls = '"
            + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }


    if(jsob.value("infcode").toInt() != 0)
    {
        QString t = jsob.value("err_msg").toString();
        QMessageBox::warning(NULL,"注意", currentInfno + " 交易失败：" + t );
        return false ;
    }

    ret2204 = jsob.value("output").toObject().value("result").toArray();

    //2204结束
    statusMsg = "2206 医保预结算。。。";
    //2206 预结算

    in = d.object();
    inpu = d.object();
    inpud = d.object();
    //putBaseIn(in, "2206A");
    if(!putBaseIn(  in, "2206A"))
    {
        return false;
    }
    inpu.insert("psn_no", personBaseinfo.value("psn_no").toString());//人员编号
    inpu.insert("mdtrt_cert_type", mdtrt_cert_type);//	就诊凭证类型

    if(mdtrt_cert_type == "03")
    {
        if( "1" == pub::getStr(cardInfo,"|",1) )
        {
            //0 社保卡， 1 老医保卡
            if(pub::getStr(cardInfo,"|",8).isEmpty())
            {
                inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",9));//老医保卡,8卡号9社保号
            }
            else
            {
                inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",8));//老医保卡,8卡号9社保号
            }
        }
        else
        {
            inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",4));   //社保卡,4卡号3社保号
        }
    }
    else if(mdtrt_cert_type == "02")
    {
        inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",2));
    }
    else if(mdtrt_cert_type == "01")
    {
        inpu.insert("mdtrt_cert_no", retScan.value("ecToken").toString());//	就诊凭证编号
    }

    //inpu.insert("med_type","110104");//	医疗类别 110104 门诊统筹， 11 普通门诊， 12 挂号
    inpu.insert("med_type","11");//	医疗类别 110104 门诊统筹， 11 普通门诊， 12 挂号
    inpu.insert("medfee_sumamt", QString::asprintf("%.2f",ui->leHjje->text().toDouble() - nonInsuAmount));//	医疗费总额
    inpu.insert("psn_setlway", "01");//	个人结算方式    01 按项目结算 02 按定额结算 09 其他 990104 按限额

    inpu.insert("mdtrt_id",  patientInfo["mdtrt_id"]);//	就诊ID
    inpu.insert("chrg_bchno", chrg_bchno);//	收费批次号
    inpu.insert("acct_used_flag","1" );//个人账户使用标志
    inpu.insert("insutype", personInsuinfo.value("insutype").toString());//险种类型

    QJsonObject ot;
    ot.insert("deve_flag","OwnSoft");
    ot.insert("dise_reim_mon","");
    ot.insert("otp_mulaid_used_flag",otp_mulaid_used_flag_0); //共济标志，  0共济，1不共济。

    inpu.insert("exp_content", ot);//	字段扩展
    inpud.insert("data",inpu);
    in.insert("input", inpud);

    indoc.setObject(in);

    //保存入参日志
    qDebug()<< currentInfno + " indoc"<<indoc;
    sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }

    reply = manager.post(request,indoc.toJson());

    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    qDebug()<<" request " + currentInfno + " is returned ";

    statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " http 请求状态错误: " + statusCode.toString());
        return false ;
    }

    err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false ;
    }

    btret = reply->readAll();
    t = QString::fromLocal8Bit(btret);

    jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);

    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 返回信息解析错误 " + json_error.errorString());
        return false ;
    }

    qDebug()<< currentInfno + " outDoc "<<jsdc;
    jsob = jsdc.object();

    //保存出参日志
    out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set tmstmp = now(),   v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +  "  where jyls = '"
            + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }

    if(jsob.value("infcode").toInt() != 0)
    {
        QString t = jsob.value("err_msg").toString();
        QMessageBox::warning(NULL,"注意", currentInfno + " 交易失败：" + t );
        return false ;
    }

    ret2206setlinfo = jsob.value("output").toObject().value("setlinfo").toObject();
    ret2206setldetail = jsob.value("output").toObject().value("setldetail").toObject();

    //医保预结算操作成功之后收费模式改为医保
    patientInfo["yb"] = "1";

    patientInfo["PAYKIND_CODE"] = "02";
    patientInfo["PACT_CODE"] = "2";
    patientInfo["PACT_NAME"] = "沈阳市保";

    ybRet["Tot_Cost"] = QString::asprintf("%.2f", ret2206setlinfo.value("medfee_sumamt").toDouble()); //
    ybRet["Pay_Cost"] = QString::asprintf("%.2f", ret2206setlinfo.value("acct_pay").toDouble()); //个人账户支付

    ybRet["Own_Cost"] = QString::asprintf("%.2f", ret2206setlinfo.value("psn_cash_pay").toDouble()); //现金支付

    ybRet["Acct_Mulaid_Pay"] = QString::asprintf("%.2f", ret2206setlinfo.value("acct_mulaid_pay").toDouble());  //共济账户支付
    ybRet["Fund_Pay_Sumamt"] = QString::asprintf("%.2f", ret2206setlinfo.value("fund_pay_sumamt").toDouble());  //基金支付
    ybRet["Pub_Cost"] = QString::asprintf("%.2f", ret2206setlinfo.value("fund_pay_sumamt").toDouble());  //基金支付

    ui->leZhzf->setText(ybRet["Pay_Cost"]);
    ui->leTczf->setText(ybRet["Pub_Cost"]);
    ui->leGjzf->setText(ybRet["Acct_Mulaid_Pay"]);

    //医保计算总金额与项目列表总金额一致，列表项目全部为医保品种
    if(ybRet["Tot_Cost"] == ui->leHjje->text())
    {
        //医保结算之后需要支付的现金
        ui->leYjxj->setText(ybRet["Own_Cost"]);
    }
    else
    {
        //项目列表中有非医保品种
        //实际需要缴费金额 = 医保品种需要支付的现金 + 非医保品种金额
        double yjje = ybRet["Own_Cost"].toDouble()
                + (ui->leHjje->text().toDouble()
                   - ybRet["Tot_Cost"].toDouble());
        ui->leYjxj->setText(QString::asprintf("%.2f",yjje));
    }

    ui->leSf->setText(ui->leYjxj->text());  //

    if(ui->leYjxj->text() == "0.00")
    {
        ui->leYjxj->setStyleSheet("color: black;");
    }
    else
    {
        ui->leYjxj->setStyleSheet("color: red;");
    }

    return true;
}

void Form_sk::on_pbPrint_clicked()   //发票打印
{
    QMap<QString, QString> mp;
    foreach(mp , lstInvoiceInfo)
    {
        mpPage.clear(); //清空页面数据
        mpPage["发票号"] = mp["invoice_no"];
        mpPage["姓名"] = patientInfo["PATIENT_NAME"];
        mpPage["性别"] = patientInfo["SEX_CODE"] == "M" ? "男" : "女";
        mpPage["收费类别"] = patientInfo["PACT_NAME"];
        mpPage["医保卡号"] = patientInfo["MCARD_NO"];
        mpPage["门诊号"] = patientInfo["CARD_NO"];
        mpPage["身份证号"] = patientInfo["IDENNO"];
        mpPage["处方医师"] = getDoctCode(mp["invoice_no"]);
        mpPage["执行科室"] = mp["dept_name"];
        QStringList fees = getFeeTypes(mp["invoice_no"]);
        int idx = 1;

        foreach(QString s, fees)
        {
            mpPage["费别"+QString::number(idx)] = s;
            idx++;
        }

        QStringList items = getItems(mp["invoice_no"]);

        if(items.size() > 10)
        {
            //大于 10 项，不分行
            QString itms = "项目名称 / 数量 / 单价 : \n";

            QStringList items = getItems(mp["invoice_no"]);

            foreach(QString s, items){
                itms += pub::getStr(s, "^", 1);
                itms += " / ";
                itms += pub::getStr(s, "^", 3);
                itms += " / ";
                itms += pub::getStr(s, "^", 4);
                itms += " ; ";

            }
            mpPage["草药明细"] = itms;  //
        }
        else
        {
            //小于等于10，逐行打印
            mpPage["项目名头"] = "项目             规格        数量     单价";
            idx = 1;

            foreach(QString s, items)
            {
                mpPage["项目"+QString::number(idx)] = pub::getStr(s, "^", 1);
                mpPage["规格"+QString::number(idx)] = pub::getStr(s, "^", 2);
                mpPage["数量"+QString::number(idx)] = pub::getStr(s, "^", 3);
                mpPage["单价"+QString::number(idx)] = pub::getStr(s, "^", 4);
                idx++;
            }
        }

        /*
        if(fees[0].indexOf("中草药") == 0)
        {
            //草药不分行
            QString itms = "药品名称 / 数量 / 单价 : \n";

            QStringList items = getItems(mp["invoice_no"]);

            foreach(QString s, items){
                itms += pub::getStr(s, "^", 1);
                itms += " / ";
                itms += pub::getStr(s, "^", 3);
                itms += " / ";
                itms += pub::getStr(s, "^", 4);
                itms += " ; ";

            }

            mpPage["草药明细"] = itms;
            qDebug()<<"草药项目明细： "<<itms;
        }
        else
        {
            //非草药，按行打印

            if(mp["printItem"] != "np") //明细项目是否打印
            {

                mpPage["项目名头"] = "项目             规格        数量     单价";
                idx = 1;
                QStringList items = getItems(mp["invoice_no"]);

                qDebug()<<"on_pbPrint_clicked , items : "<< items;

                foreach(QString s, items)
                {
                    mpPage["项目"+QString::number(idx)] = pub::getStr(s, "^", 1);
                    mpPage["规格"+QString::number(idx)] = pub::getStr(s, "^", 2);
                    mpPage["数量"+QString::number(idx)] = pub::getStr(s, "^", 3);
                    mpPage["单价"+QString::number(idx)] = pub::getStr(s, "^", 4);
                    idx++;
                    if(idx > 10)
                    { //每张发票显示项目明细最多10项
                        break;
                    }
                }
            }
        }
        */


        mpPage["合计"] = mp["tot_cost"];
        mpPage["大写"] = pub::bigW(mp["tot_cost"].toDouble());
        mpPage["医院名称"] = pub::hos_name;
        mpPage["操作员"] = pub::usr_code;
        QDateTime dt = QDateTime::currentDateTime();
        QString d = dt.toString("yyyy");
        d.append("    ");
        d.append(dt.toString("MM"));
        d.append("    ");
        d.append(dt.toString("dd"));
        d.append("    ");
        d.append(dt.toString("hh:mm:ss"));

        mpPage["日期"] = d;
        if(patientInfo["yb"] == "1")
        {
            //医保支付，显示支付之后的卡余额
            mpPage["卡余额"] = mp["ybzhye"];
        }

        if(qFuzzyCompare( 0, mp["gjzf"].toDouble()))
        {
            mpPage["账户"] = mp["pay_cost"];
        }
        else
        {
            mpPage["账户"] = mp["pay_cost"] + " （家庭共济：" + mp["gjzf"] + "）";
        }

        if(!qFuzzyCompare( 0, mp["pub_cost"].toDouble()))
        {
            mpPage["统筹"] = mp["pub_cost"]
                    + " （"
                    + ((qFuzzyCompare( 0, mp["hifp_pay"].toDouble())) ? "" : "统筹基金支付：" + mp["hifp_pay"])
                    + ((qFuzzyCompare( 0, mp["cvlserv_pay"].toDouble())) ? "" : " / 其他支付：" + mp["cvlserv_pay"])
                    + ((qFuzzyCompare( 0, mp["hifes_pay"].toDouble())) ? "" : " / 补充险支付：" + mp["hifes_pay"])
                    + ((qFuzzyCompare( 0, mp["hifmi_pay"].toDouble())) ? "" : " / 大额支付：" + mp["hifmi_pay"])
                    + ((qFuzzyCompare( 0, mp["hifob_pay"].toDouble())) ? "" : " / 大病支付：" + mp["hifob_pay"])
                    + ((qFuzzyCompare( 0, mp["maf_pay"].toDouble())) ? "" : " / 医疗救助：" + mp["maf_pay"])
                    + ((qFuzzyCompare( 0, mp["oth_pay"].toDouble())) ? "" : " / 其他：" + mp["oth_pay"])
                    + "）";
        }

        double yf = mp["own_cost"].toDouble();  //应付现金
        double sf =  mp["real_cost"].toDouble();    //实付现金

        if(qFuzzyCompare(yf, sf))
        {
            //无四舍五入
            mpPage["个人"] =mp["own_cost"];
        }
        else
        {
            mpPage["个人"] =mp["real_cost"] + " (" + mp["own_cost"] + ")";
        }

        printPage();
    }
}

void Form_sk::printPage()
{
    pnt->begin(prt);
    QString item, mode,print_item,font,item_type;
    QFont ft=QFont();
    double top,left,width,height,size;
    int position;
    qrm->prepare("select p_type,p_item,p_top,p_left,p_width,p_height,"
                 "p_font_name,p_font_size,p_position,p_mode,p_print_item,"
                 "p_item_type from com_printer_setting where p_type = '门诊收据'"
                 " and p_item_type in ('item','text')");
    if(!qrm->exec())
    {
        QMessageBox::information(this,"错误","读取处方格式数据表失败：" + qrm->lastError().text());
        return;
    }

    while(qrm->next())
    {
        item = qrm->value("p_item").toString();    //项目名称
        top = qrm->value("p_top").toDouble();
        left = qrm->value("p_left").toDouble();
        width = qrm->value("p_width").toDouble();
        height = qrm->value("p_height").toDouble();
        font = qrm->value("p_font_name").toString();
        size = qrm->value("p_font_size").toDouble();
        position = qrm->value("p_position").toInt();
        mode = qrm->value("p_mode").toString();
        print_item = qrm->value("p_print_item").toString();
        item_type = qrm->value("p_item_type").toString();
        item = mpPage.value(item);  //根据项目名称，在mpPage 取回对应项目值

        //qDebug()<<"in printPage , item : "<<item;
        //qDebug()<<"in printPage , print_item : "<<print_item;

        if(item.isEmpty())
        {
            continue;   //空值不打印
        }
        QString outText;    //输入文本

        if(mode == "1")
        {
            outText = print_item + "：" + item;
        }
        else if(mode == "0")
        {
            outText =  item;
        }
        else if(mode == "3")
        {
            outText =  print_item ;
        }

        //qDebug()<<"in printPage , outText : "<<outText;

        //QFontMetrics fm(font, prt);
        ft.setPixelSize(int(ptScale * size));

        //qDebug()<<"in printPage , ptPixelSize default : " <<QString::number(int(ptScale * size));

        ft.setFamily(font);
        QFontMetrics fm(ft, prt);
        int pixelsWide = fm.width(outText);

        //qDebug()<<"in printPage , Width : "<<QString::number(pixelsWide ) <<","<<QString::number(width * ptScale) ;

        if( item_type == "item" && pixelsWide > width * ptScale )
        {
            // 打印模式为 item， 且 超过预定格式宽度，缩小字号
            size = size * ( width * ptScale / pixelsWide );//
            ft.setPixelSize(int(ptScale * size));
            ft.setFamily(font);

            //qDebug()<<"in printPage , ptPixelSize real : " <<QString::number(int(ptScale * size));
        }

        if(item_type == "text")
        {
            position = Qt::TextWordWrap | Qt::AlignLeft;// Qt::AlignVCenter |
        }

        pnt->setFont(ft);
        const QRect rect = QRect( left * ptScale, top * ptScale, width * ptScale, height * ptScale);
        QRect boundingRect;
        pnt->drawText(rect, position, outText, &boundingRect);
    }
    pnt->end();
}

void Form_sk::uiInit()
{
    ui->pbYbjs->setEnabled(false);  //医保结算按钮
    ui->pbSfbc->setEnabled(false);  //收费确认按钮
    ui->pbPrint->setEnabled(false); //打印
    mdXmmx.setQuery(NULL);          //项目明细列表清空
    ui->leHjje->setText("");        //合计金额
    ui->leYjxj->setText("");        //应收金额
    ui->leZhzf->setText("");        //账户支付
    ui->leTczf->setText("");        //基金支付
    ui->leGjzf->setText("");        //共济支付
    ui->rbX->setChecked(true);      //现金
}

void Form_sk::onTimeOut()
{
    if(ui->lbMode->text().isEmpty()){
        ui->lbMode->setText(tmString);
    }else{
        ui->lbMode->setText("");
    }
    qApp->processEvents();  //刷新显示
}

bool Form_sk::putBaseIn( QJsonObject &in, QString code)
{

    currentMsgid = pub::getYbStrJ(code, patientInfo["CLINIC_CODE"]);   //
    if(currentMsgid.isEmpty())
    {
        QThread::msleep(1000);
        currentMsgid = pub::getYbStrJ(code, patientInfo["CLINIC_CODE"]);   //
        if(currentMsgid.isEmpty())
        {
            QMessageBox::information(this,"note",  code + " 申请交易流水号失败！");
            return false; //未能成功申请交易流水号
        }
    }

    currentInfno = code;

    if(code == "2207A")
    {
        msgid2207 = currentMsgid;
    }

    in.insert("infno", code);
    in.insert( "msgid", currentMsgid);
    in.insert("mdtrtarea_admvs", pub::hos_insuplc);

    if(!personInsuinfo.value("insuplc_admdvs").toString().isEmpty())
    {
        in.insert("insuplc_admdvs",personInsuinfo.value("insuplc_admdvs").toString());
    }

    in.insert("insuplc_admdvs","210100");
    in.insert("recer_sys_code", "OwnSoft");
    in.insert("dev_no","");
    in.insert("dev_safe_info","");
    in.insert("cainfo", pub::hos_secretcode);
    in.insert("signtype","");
    in.insert("infver", "V1.0");
    in.insert("opter_type", "1");
    in.insert("opter", pub::usr_code);
    in.insert("opter_name", pub::usr_name);
    in.insert("inf_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
    in.insert("fixmedins_code", pub::hos_ybbh);
    in.insert("fixmedins_name", pub::hos_name);
    in.insert("sign_no", pub::sign_no);

    return true;
}

bool Form_sk::searchBaseData()
{
    qDebug()<<"提取医保结算基础数据。。。\n";
    //取最后一条记录
    qro->prepare("select balance_no, remark, person_type, reg_no, individualbalance, mdtrt_id, "
                 " mdtrt_cert_type, ipt_otp_no, insuplc_admdvs"
                 " from Fin_Ipr_Siinmaininfo where Inpatient_No = :Inpatient_No And Type_Code = '1' "
                 " order by balance_no desc"
                 );
    qro->bindValue(":Inpatient_No", patientInfo["CLINIC_CODE"]);

    if(!qro->exec())
    {
        qDebug()<<"查询 fin_ipr_siinmaininfo 失败。\n";
        QMessageBox::information(this,"错误", "查询 Fin_Ipr_Siinmaininfo 失败！"+qro->lastError().text());
        qDebug()<<qro->lastQuery();
        return false;
    }

    if(!qro->next())
    {
        qDebug()<<"未使用医保挂号。\n";
        QMessageBox::information(this,"错误","未使用医保挂号，不能使用医保结算！");
        return false;
    }

    patientInfo["maxBalanceNo"] = qro->value(0).toString();
    patientInfo["remark"] = qro->value(1).toString();   //参保状态
    patientInfo["personType"] = qro->value(2).toString();
    patientInfo["regNo"] = qro->value(3).toString();    //社保号
    patientInfo["mdtrt_id"] = qro->value(5).toString();    //就诊id
    mdtrt_cert_type = qro->value(6).toString();    //支付方式 01电子，02身份证，03社保卡
    patientInfo["ipt_otp_no"] = qro->value(7).toString();    //
    patientInfo["insuplc_admdvs"] = qro->value(8).toString();    //

    //医保模式
    if(mdtrt_cert_type == "03")
    {
        ui->rbK->setChecked(true);
    }
    else if(mdtrt_cert_type == "01")
    {
        ui->rbM->setChecked(true);
    }
    else if(mdtrt_cert_type == "02")
    {
        ui->rbZ->setChecked(true);
    }
    else
    {
        qDebug()<<"找不到有效的医保支付方式。\n";
        QMessageBox::information(this,"错误","找不到有效的医保支付方式！");
        ui->rbX->setChecked(true);
        return false;
    }

    //查询诊断
    diag.clear();// 清空诊断列表

    sq = "select t.clinicdiag_code, t.clinicdiag_name, "
         "doct_code,doct_name,dept_code,oper_date"
         " from met_ord_recipedetail t "
         " where t.clinic_code = '"
            + patientInfo["CLINIC_CODE"]
            + "' and status <> '3' and status <> '4' "
              " order by t.oper_date desc";
    qDebug()<<"提取诊断信息："<<sq<<"\n";

    if(!qro->exec(sq))
    {
        QMessageBox::information(this,"error","从 met_ord_recipedetail 提取诊断信息错误!");
        return false ;
    }

    if(!qro->next())
    {
        QMessageBox::information(this,"错误","找不到有效的诊断，无法向医保中心上传！");
        return false;
    }

    //QString docCod,docName,depCod;
    QMap<QString,QString> mp;
    bool find;  //是否已经存在该诊断

    while(true)
    {
        find  = false;

        foreach (mp, diag)
        {
            if(mp["diagCode"] == qro->value(0).toString() )
            {
                find = true;
                break;
            }
        }

        if(!find)
        {
            //未找到，插入新值
            mp["diagCode"] = qro->value(0).toString();
            mp["diagName"] = qro->value(1).toString();
            mp["doctCode"] = qro->value(2).toString();
            mp["doctName"] = qro->value(3).toString();
            mp["deptCode"] = qro->value(4).toString();
            mp["operDate"] = qro->value(5).toDateTime().toString("yyyy-MM-dd HH:mm:ss");

            diag << mp;
        }

        if(!qro->next())
        {
            break;
        }
        //qDebug()<<" diag qro->value(0).toString()"<<qro->value(0).toString();
    }
    return true;
}

bool Form_sk::scanCode()
{

    QJsonObject in; //入参
    QJsonObject inpu,inpud; // 入参 input 段
    QJsonDocument indoc;

    inpu.insert("businessType", "01301");     //用码类型, 结算
    inpu.insert("officeId", pub::dp_code);
    inpu.insert("officeName", pub::dp_name);
    inpu.insert("operatorId", pub::usr_code);
    inpu.insert("operatorName", pub::usr_name);
    inpu.insert("orgId", pub::hos_ybbh);
    in.insert("data", inpu);
    in.insert("orgId", pub::hos_ybbh);
    in.insert("transType", "ec.query");
    indoc.setObject(in);

    QString inp = indoc.toJson();

    char p1[8192];
    int ret = pub::EcQuery( inp.toLocal8Bit().data() , p1 );

    qDebug()<<"扫码 "<<indoc;


    if(ret != 0)
    {
        QMessageBox::information(this,"错误","医保扫码失败！ ");
        qDebug()<<"医保扫码失败";

        return false;
    }

    QString ret1 = QString::fromLocal8Bit(p1); //获取出参

    QJsonParseError json_error;
    QJsonDocument jsdc = QJsonDocument::fromJson(ret1.toUtf8(), &json_error);

    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意","scanCode 返回信息解析错误 " + json_error.errorString());

        return false;
    }
    qDebug()<< "scan code outDoc "<<jsdc;

    sq = "insert into com_business (tmstmp,ywbh,user,jysj,jyfs,v_in,v_out) values "
         "(now(),'codeScan','" + pub::usr_code + "',DATE_FORMAT(now(),'%Y-%m-%d %T'),'code','"
            + indoc.toJson(QJsonDocument::Compact) + "','" + jsdc.toJson(QJsonDocument::Compact) + "')";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"注意","保存医保动态库交易日志失败！ ");
        qDebug()<<sq;
    }

    QJsonObject jsob = jsdc.object();

    if( !qFuzzyCompare(jsob.value("code").toDouble() , 0))
    {
        QMessageBox::information(this,"注意","scanCode 动态库返回失败: " + jsob.value("message").toString());
        return false;
    }

    retScan = jsob.value("data").toObject();
    return true;

}

bool Form_sk::readCard()
{

    QJsonObject inpu; // 入参 input 段
    QJsonDocument indoc;

    int ret = -1;
    char p1[2048];
    char p2[8192];

    ret = pub::ReadCardBas(p1, p2);

    if(ret != 0)
    {
        QMessageBox::information(this,"错误","医保读卡失败！ ");
        qDebug()<<"医保读卡失败";

        return false;

    }
    cardInfo = QString::fromLocal8Bit(p1); //获取出参
    busiCardInfo= QString::fromLocal8Bit(p2); //获取出参

    QString ret1 = cardInfo;
    QString ret2 = busiCardInfo;

    sq = "insert into com_business (tmstmp,ywbh,user,jysj,jyfs,v_in,v_out) values "
         "(now(),'cardRead','" + pub::usr_code + "',DATE_FORMAT(now(),'%Y-%m-%d %T'),'card','','"
            + ret1 + "^" + ret2 + "')";
    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"注意","保存医保动态库交易日志失败！ ");
        qDebug()<<sq;
    }

    return true;
}

bool Form_sk::readIdCard()
{

    QJsonObject inpu; // 入参 input 段
    QJsonDocument indoc;

    int ret = -1;
    char p1[10240];
    char p2[10240];

    ret = pub::ReadSFZ(p1, p2);

    if(ret != 0)
    {
        QMessageBox::information(this,"错误","身份证读卡失败！ ");
        qDebug()<<"身份证读卡失败";

        return false;

    }
    cardInfo = QString::fromLocal8Bit(p1); //获取出参
    busiCardInfo= QString::fromLocal8Bit(p2); //获取出参

    QString ret1 = cardInfo;
    QString ret2 = busiCardInfo;

    sq = "insert into com_business (tmstmp,ywbh,user,jysj,jyfs,v_in,v_out) values "
         "(now(),'cardRead','" + pub::usr_code + "',DATE_FORMAT(now(),'%Y-%m-%d %T'),'card','','"
            + ret1 + "^" + ret2 + "')";
    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"注意","保存医保动态库交易日志失败！ ");
        qDebug()<<sq;
    }

    return true;
}

void Form_sk::push_5465()
{
    qDebug()<<"Form_sk::push_5465()\n";

    sq = " select * from zjzf_5465_push "
         " where clinic_code = '%1' and dept_code = '%2' and push_state = '0'";
    sq = sq.arg(patientInfo["CLINIC_CODE"]).arg(patientInfo["regDeptCode"]);
    qrm->exec(sq);
    while(qrm->next())
    {
        // 构建JSON请求体
        QJsonObject json;
        QJsonObject json_sub,json_sub_sub;

        json_sub_sub["outBizType"] = "HOSPITAL_PAYMENT";
        json_sub_sub["orderStatus"] = "MERCHANT_CLOSED";

        json_sub["aliExtData"] = json_sub_sub;

        json_sub["pushType"] = "ZHYB_APP";
        json_sub["orgCodg"] = pub::hos_ybbh;
        json_sub["hisAreaCody"] = qrm->value("dept_code").toString();

        json_sub["medOrgOrd"] = qro->value("medOrgOrd").toString();

        json_sub["psnCertType"] = "01";
        json_sub["certno"] = qro->value("patient_idenno").toString();
        json_sub["psnName"] = qro->value("patient_name").toString();

        QString info_ret;
        QJsonObject js_ret;

        request_zjzf.setUrl(QUrl(pub::zj_push_ip + "/medinsOrd/pushMsg"));

        if(pub::call_busi_push("5465", json_sub, info_ret, js_ret, "" , true, manager, request_zjzf, patientInfo["CLINIC_CODE"]))
        {
            qDebug()<<"pub::call_busi_push 5465 return : " << info_ret << "\n";

            sq = " update zjzf_5465_push "
                 " set push_state = '1',"
                 " end_time = now(),"
                 " end_oper_code = '%1'"
                 " where medOrgOrd = '%2'";
            sq = sq.arg(pub::usr_code).arg(json_sub["medOrgOrd"].toString());
            qDebug()<<"写入订单终结状态："<<sq<<"\n";
            qrm->exec(sq);
        }
        else
        {
            qDebug()<<"pub::call_busi_push 5465 return : " << info_ret << "\n";
        }
    }
}

void Form_sk::save_5465()
{
    qDebug()<<"Form_sk::save_5465()\n";

    //保存诊间支付消息

    foreach(QString rcp, recipe_list_5465)
    {
        sq = " update zjzf_5465_push set "
             " push_state = '5',"
             " end_time = now(),"
             " end_oper_code = '%3' "
             " where clinic_code = '%1'"
             " and push_state = '0' and recipe_no like '%%2%'";
        sq = sq.arg(patientInfo["CLINIC_CODE"]).arg(rcp).arg(pub::usr_code);
        qDebug()<<"写入push_5465:"<<sq<<"\n";
        qrm->exec(sq);
    }

}

bool Form_sk::ybjs(QString ivno, QSqlQuery * qro)
{
    //真正执行收费操作时需要按每张发票计算医保结算结果
    nonInsuAmount = 0;
    if( ivno.isEmpty() )
    {
        //发票号空
        return false;
    }

    //2204,费用明细上传
    //预结算不分发票只算总数，医保结算时需要按每张发票计算，所以要清除数据重新上传。

    QJsonObject in, inpu, inpud;
    QJsonDocument indoc, d;

    if(!putBaseIn(  in, "2204")) return false;

    QJsonArray jsar;
    qro->exec("select seq_ftp_seq.nextval from dual");
    qro->next();
    chrg_bchno = qro->value(0).toString();

    QMap<QString, QString> mp;

    foreach(mp, lstItemDetail)
    {

        //非本发票号关联的项目，不计算
        if( mp["invoice_no"] != ivno)
        {
            qDebug()<<"非本发票品种"<<patientInfo["currentInvoNo"]<<mp["TRADE_NAME"];
            continue;   //不进行本轮计算
        }

        if( mp["has_compare"] == "0")
        {
            qDebug()<<"非医保品种"<<mp["TRADE_NAME"];
            nonInsuAmount += mp["RETAIL_PRICE"].toDouble() * mp["APPLY_NUM"].toDouble() / mp["PACK_QTY"].toDouble();
            continue;   //非医保品种，不进行医保计算
        }

        inpu.insert("feedetl_sn", mp["MO_ORDER"]);//	费用明细流水号
        inpu.insert("mdtrt_id", patientInfo["mdtrt_id"]);//	就诊ID
        inpu.insert("psn_no", personBaseinfo.value("psn_no").toString());//	人员编号
        inpu.insert("chrg_bchno", chrg_bchno);//	收费批次号
        //inpu.insert("rxno", personBaseinfo.value("psn_no").toString());//	处方号
        inpu.insert("rx_circ_flag", "0");//	外购处方标志
        inpu.insert("fee_ocur_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));//	费用发生时间

        /*2024-12-23 增加*/
        inpu.insert("sin_dos_dscr", mp["DOSE_ONCE"] + mp["DOSE_UNIT"]);// 单次剂量描述
        inpu.insert("used_frqu_dscr", mp["freq_name"]);// 使用频次描述
        inpu.insert("medc_way_dscr", mp["USE_NAME"]);// 用药途径描述
        inpu.insert("prd_days", mp["DAYS"]);//	药品可用日期
        /*2024-12-23*/
        inpu.insert("med_list_codg", mp["center_code"]);//	医疗目录编码-00110200001000003

        inpu.insert("medins_list_codg", mp["item_code"]);//	医药机构目录编码
        inpu.insert("det_item_fee_sumamt", mp["own_cost"]);//	明细项目费用总额

        inpu.insert("cnt", QString::number( mp["APPLY_NUM"].toInt() ) );//	数量
        inpu.insert("pric",  QString::number(mp["RETAIL_PRICE"].toDouble() / mp["PACK_QTY"].toDouble(),'f',6) );//	单价
        inpu.insert("bilg_dept_codg", mp["doct_dept"]);//	开单科室编码

        qro->exec("select dept_name from com_department where dept_code = '" + mp["doct_dept"] + "'");
        qro->next();
        inpu.insert("bilg_dept_name", qro->value(0).toString());//	开单科室名称

        inpu.insert("bilg_dr_codg", mp["doct_si_code"]);//	开单医生编码
        inpu.insert("bilg_dr_name", mp["doct_name"]);//	开单医师姓名
        inpu.insert("hosp_appr_flag", "1");//	医院审批标志

        QString tmp_sql;

        tmp_sql = " select si_code, empl_name "
                  " from com_loginlog "
                  " where login_date > trunc(sysdate) "
                  " and logout_date is null and "
                  " dept_code = '"
                + mp["DRUG_DEPT_CODE"] + "' order by login_date desc";

        qro->exec(tmp_sql);

        qro->next();

        if(!qro->value(0).toString().isEmpty())
        {
            inpu.insert("orders_dr_code", qro->value(0).toString());//审方药师编码
            inpu.insert("orders_dr_name", qro->value(1).toString());//审方药师姓名
        }


        jsar.append(inpu);

    }

    if(jsar.size() == 0)
    {
        QMessageBox::warning(NULL,"注意"," 明细项目列表不允许为空！ " );
        return false ;
    }

    inpud.insert("feedetail", jsar);
    in.insert("input", inpud);
    indoc.setObject(in);
    qDebug()<< currentInfno + " indoc"<<indoc;

    indoc.setObject(in);

    //保存入参日志
    qDebug()<< currentInfno + " indoc"<<indoc;
    sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }

    QNetworkReply* reply = manager.post(request,indoc.toJson());
    QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    qDebug()<<" request " + currentInfno + " is returned ";

    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " http 请求状态错误: " + statusCode.toString());
        return false;
    }

    QNetworkReply::NetworkError err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false;
    }

    QByteArray btret = reply->readAll();
    QString t = QString::fromLocal8Bit(btret);

    QJsonParseError json_error;
    QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 返回信息解析错误 " + json_error.errorString());

        return false;
    }
    qDebug()<< currentInfno + " outDoc "<<jsdc;
    QJsonObject jsob = jsdc.object();

    //保存出出参日志
    QString out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set tmstmp = now(),   v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +  "  where jyls = '"
            + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }


    if(jsob.value("infcode").toInt() != 0)
    {
        QString t = jsob.value("err_msg").toString();
        QMessageBox::warning(NULL,"注意", currentInfno + " 交易失败：" + t );
        return false;
    }

    ret2204 = jsob.value("output").toObject().value("result").toArray();

    //2204结束

    //2207A 开始

    in = d.object();
    inpu = d.object();
    inpud = d.object();

    //putBaseIn(in, "2207A");
    if(!putBaseIn(  in, "2207A")) return false;


    inpu.insert("psn_no", personBaseinfo.value("psn_no").toString());//人员编号
    inpu.insert("mdtrt_cert_type", mdtrt_cert_type);//	就诊凭证类型

    if(mdtrt_cert_type == "03")
    {
        if( "1" == pub::getStr(cardInfo,"|",1) )
        {
            //0 社保卡， 1 老医保卡
            if(pub::getStr(cardInfo,"|",8).isEmpty())
            {
                inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",9) + "|" + busiCardInfo);//老医保卡,8卡号9社保号
            }
            else
            {
                inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",8) + "|" + busiCardInfo);//老医保卡,8卡号9社保号
            }
        }
        else
        {
            inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",4) + "|" + busiCardInfo);   //社保卡,4卡号3社保号
        }
    }
    else if(mdtrt_cert_type == "02")
    {
        inpu.insert("mdtrt_cert_no", pub::getStr(cardInfo,"|",2) + "|" + busiCardInfo);

    }
    else if(mdtrt_cert_type == "01")
    {
        inpu.insert("mdtrt_cert_no", retScan.value("ecToken").toString());//	就诊凭证编号
    }

    //inpu.insert("med_type","110104");//	医疗类别 110104 门诊统筹， 11 普通门诊， 12 挂号
    inpu.insert("med_type", "11");//医疗类别    12,挂号


    double cost = 0;
    QMap<QString, QString> mmp;

    //计算金额
    foreach(mmp, lstInvoiceInfo)
    {
        if( mmp["invoice_no"] == ivno)
        {
            cost = mmp["ocst"].toDouble();
            break;   //
        }
    }

    if(qFuzzyCompare(cost, 0))
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 失败，查不到发票金额。" );
        return false;
    }

    //计算追溯码
    int code_count_all = 0;
    foreach(mmp, lstItemDetail)
    {
        qDebug()<<"TRADE_NAME : "<<mmp["TRADE_NAME"];

        int apply_num = mmp["APPLY_NUM"].toInt();
        int pack_qty = mmp["PACK_QTY"].toInt();
        int id_code_count = mmp["id_code_count"].toInt();
        int code_num = 0;

        if(mmp["drug_flag"] != "1")
        {
            //西药，中成药才有追溯码
            continue;
        }

        if( id_code_count == 0)
        {
            //无码品种

            qDebug()<<"无码品种";
            continue;
        }
        else if( id_code_count == 1)
        {
            qDebug()<<"不拆零品种，一件一码";
            //不拆零品种，一件一码
            code_num = apply_num / pack_qty;
        }
        else
        {
            qDebug()<<"可拆零，多件一码";
            //可拆零，多件一码
            code_num = apply_num / pack_qty / id_code_count;
            if((apply_num / pack_qty) % id_code_count > 0)
            {
                //有余数，需要加 1
                code_num += 1;
            }
        }

        code_count_all += code_num;
    }

    qDebug()<<"id_code_count : "<<QString::number(code_count_all);

    inpu.insert("medfee_sumamt", QString::asprintf("%.2f", cost - nonInsuAmount));//	医疗费总额
    inpu.insert("psn_setlway", "01");//	个人结算方式
    inpu.insert("mdtrt_id",  patientInfo["mdtrt_id"]);//	就诊ID
    inpu.insert("chrg_bchno", chrg_bchno);//	收费批次号
    inpu.insert("acct_used_flag","1" );//个人账户使用标志
    inpu.insert("insutype", personInsuinfo.value("insutype").toString());//险种类型

    inpu.insert("minpacunt_drug_trac_cnt", code_count_all);//应上传最小包装药品追溯码数量
    inpu.insert("mcs_trac_cnt", 0);//应上传耗材追溯码数量

    QJsonObject qt;
    qt.insert("deve_flag","OwnSoft");
    qt.insert("dise_reim_mon","");
    qt.insert("otp_mulaid_used_flag",otp_mulaid_used_flag_0); //共济标志，  0共济，1不共济。

    //20250705增加
    qt.insert("cent_drug_flag", "0"); //集中配药标志,0否，1是。

    inpu.insert("exp_content", qt);//	字段扩展
    inpud.insert("data",inpu);
    in.insert("input", inpud);

    indoc.setObject(in);
    //保存入参日志
    qDebug()<< currentInfno + " indoc"<<indoc;
    sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }

    reply = manager.post(request,indoc.toJson());
    //QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    qDebug()<<" request " + currentInfno + " is returned ";

    statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " http 请求状态错误: " + statusCode.toString());
        return false;
    }

    //QNetworkReply::NetworkError
    err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false;
    }

    btret = reply->readAll();
    t = QString::fromLocal8Bit(btret);

    //QJsonParseError json_error;

    jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 返回信息解析错误 " + json_error.errorString());

        return false;
    }
    qDebug()<< currentInfno + " outDoc "<<jsdc;
    jsob = jsdc.object();

    out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set tmstmp = now(),   v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +  "  where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }

    if(jsob.value("infcode").toInt() != 0)
    {
        QString t = jsob.value("err_msg").toString();
        QMessageBox::warning(NULL,"注意", currentInfno + " 交易失败：" + t );
        return false;
    }

    ret2207setlinfo = jsob.value("output").toObject().value("setlinfo").toObject();
    ret2207setldetail = jsob.value("output").toObject().value("setldetail").toObject();

    ybRet.clear();

    ybRet["Tot_Cost"] = QString::asprintf("%.2f", ret2207setlinfo.value("medfee_sumamt").toDouble()); //
    ybRet["Pay_Cost"] = QString::asprintf("%.2f", ret2207setlinfo.value("acct_pay").toDouble()); //账户支付

    ybRet["Own_Cost"] = QString::asprintf("%.2f", ret2207setlinfo.value("psn_cash_pay").toDouble()); //现金支付
    ybRet["balc"] = QString::asprintf("%.2f", ret2207setlinfo.value("balc").toDouble()); //个人账户余额

    ybRet["Acct_Mulaid_Pay"] = QString::asprintf("%.2f", ret2207setlinfo.value("acct_mulaid_pay").toDouble());  //共济账户支付
    ybRet["Fund_Pay_Sumamt"] = QString::asprintf("%.2f", ret2207setlinfo.value("fund_pay_sumamt").toDouble());  //基金支付
    ybRet["Pub_Cost"] = QString::asprintf("%.2f", ret2207setlinfo.value("fund_pay_sumamt").toDouble());  //统筹

    ybRet["hifp_pay"] = QString::asprintf("%.2f", ret2207setlinfo.value("hifp_pay").toDouble());  //基金支付
    ybRet["hifes_pay"] = QString::asprintf("%.2f", ret2207setlinfo.value("hifes_pay").toDouble());  //补充险
    ybRet["hifmi_pay"] = QString::asprintf("%.2f", ret2207setlinfo.value("hifmi_pay").toDouble());  //大额
    ybRet["hifob_pay"] = QString::asprintf("%.2f", ret2207setlinfo.value("hifob_pay").toDouble());  //大病
    ybRet["maf_pay"] = QString::asprintf("%.2f", ret2207setlinfo.value("maf_pay").toDouble());  //医疗救助
    ybRet["oth_pay"] = QString::asprintf("%.2f", ret2207setlinfo.value("oth_pay").toDouble());  //其他
    ybRet["cvlserv_pay"] = QString::asprintf("%.2f", ret2207setlinfo.value("cvlserv_pay").toDouble());  //公务员医疗补助资金支出

    ybRet["nonInsuAmount"] = QString::asprintf("%.2f",nonInsuAmount);
    patientInfo["ybZhye"] = ybRet["balc"];

    qDebug()<<"ybRet "<<ybRet;

    //写入当前医保结算发票的应缴现金
    for(int id = 0; id<lstInvoiceInfo.length(); id++)
    {
        if(lstInvoiceInfo[id]["invoice_no"] == ivno)
        {
            //处理处方中包含非医保品种的情况
            double ybhj = ybRet["Tot_Cost"].toDouble(); //医保合计
            double fphj = lstInvoiceInfo[id]["tot_cost"].toDouble();   //发票合计
            double yjje = ybRet["Own_Cost"].toDouble();    //应缴现金
            //本发票医保计算总金额与项目列表总金额一致，列表项目全部为医保品种
            if( !qFuzzyCompare(ybhj, fphj))
            {
                //项目列表中有非医保品种
                //实际需要缴费金额 = 医保品种需要支付的现金 + 非医保品种金额
                yjje = yjje + fphj - ybhj;
            }

            lstInvoiceInfo[id]["real_cost"] = QString::asprintf("%.2f",yjje);
            lstInvoiceInfo[id]["pay_cost"] = ybRet["Pay_Cost"];
            lstInvoiceInfo[id]["gjzf"] = ybRet["Acct_Mulaid_Pay"];
            lstInvoiceInfo[id]["pub_cost"] = ybRet["Pub_Cost"];
            lstInvoiceInfo[id]["own_cost"] = QString::asprintf("%.2f",yjje);
            lstInvoiceInfo[id]["ybzhye"] = ybRet["balc"];
            lstInvoiceInfo[id]["nonInsuAmount"] = QString::asprintf("%.2f",nonInsuAmount);

            lstInvoiceInfo[id]["hifp_pay"] = ybRet["hifp_pay"];
            lstInvoiceInfo[id]["hifes_pay"] = ybRet["hifes_pay"];
            lstInvoiceInfo[id]["hifmi_pay"] = ybRet["hifmi_pay"];
            lstInvoiceInfo[id]["hifob_pay"] = ybRet["hifob_pay"];
            lstInvoiceInfo[id]["maf_pay"] = ybRet["maf_pay"];
            lstInvoiceInfo[id]["oth_pay"] = ybRet["oth_pay"];
            lstInvoiceInfo[id]["cvlserv_pay"] = ybRet["cvlserv_pay"];

            ybRet["afterPay"] = ybRet["balc"];
        }
    }
    return true;    //医保交易成功标志

}

bool Form_sk::saveSI(QString invo_no, QSqlQuery * qro_tmp)
{
    //invo_no发票号
    QString balanceNo = QString::number(patientInfo["maxBalanceNo"].toInt() + 1);
    patientInfo["maxBalanceNo"] = balanceNo;
    patientInfo["currentInvoNo"] = invo_no;     // patientInfo["currentInvoNo"]不为空，执行实际医保结算
    qDebug()<<"si"<<patientInfo["currentInvoNo"]<<"balanceNo"<<balanceNo;
    tmString = "医保数据结算，当前发票号：" + invo_no;
    ui->lbMode->setText(tmString);
    qApp->processEvents();  //刷新显示

    if(!ybjs(invo_no, qro_tmp))
    {
        return false;
    }

    qro_tmp->prepare("insert into fin_ipr_siinmaininfo ("
                 " non_insu_amount,insutype, clr_type, clr_way, hifp_pay, med_type, medfee_sumamt, preselfpay_amt, "
                 " inscp_scp_amt, psn_cash_pay, fund_pay_sumamt, acct_pay, acct_mulaid_pay, psn_type,"
                 "insuplc_admdvs,psn_no,mdtrt_id,ipt_otp_no,msgid,setl_id,mdtrt_cert_type,"
                 "trans_type,Inpatient_No,Balance_No,Invoice_No,Medical_Type,Patient_No,"
                 "Card_No,Mcard_No,App_No,Procreate_Pcno,Si_Begindate,Si_State,Name,"
                 "Sex_Code,Idenno,Spell_Code,Birthday,Empl_Type,Work_Name,Clinic_Diagnose,"
                 "Dept_Code,Dept_Name,Paykind_Code,Pact_Code,Pact_Name,Bed_No,In_Date,"
                 "In_Diagnosedate,In_Diagnose,In_Diagnosename,Oper_Code,Oper_Date,"
                 "Reg_No,Fee_Times,Hos_Cost,Year_Cost,Out_Date,Out_Diagnose,"
                 "Out_Diagnosename,Balance_Date,Tot_Cost,Pay_Cost,Pub_Cost,Item_Paycost,"
                 "Base_Cost,Item_Ylcost,Item_Paycost2,Own_Cost,Over_Cost,Valid_Flag,"
                 "Balance_State,Remark,Official_Cost,Type_Code,Person_Type,"
                 "Primarydiagnosecode,Operatecode1,Operatecode2,Operatecode3,"
                 "Primarydiagnosename,overtake_owncost,BUSINESSSEQUENCE,"
                 "SERIOUSILLNESS_IN_COST,SERIOUSILLNESS_COST,SERIOUSILLNESS_TOTAL,individualbalance"
                 ") values( "
                 + ybRet["nonInsuAmount"] + ","
                 "'" + ret2207setlinfo.value("insutype").toString() + "',"
                 "'" + ret2207setlinfo.value("clr_type").toString() + "',"
                 "'" + ret2207setlinfo.value("clr_way").toString() + "',"
                 "'" + QString::asprintf("%.2f",ret2207setlinfo.value("hifp_pay").toDouble()) + "',"
                 "'" + ret2207setlinfo.value("med_type").toString() + "',"
                 "'" + QString::asprintf("%.2f",ret2207setlinfo.value("medfee_sumamt").toDouble()) + "',"
                 "'" + QString::asprintf("%.2f",ret2207setlinfo.value("preselfpay_amt").toDouble()) + "',"
                 "'" + QString::asprintf("%.2f",ret2207setlinfo.value("inscp_scp_amt").toDouble()) + "',"
                 "'" + QString::asprintf("%.2f",ret2207setlinfo.value("psn_cash_pay").toDouble()) + "',"
                 "'" + QString::asprintf("%.2f",ret2207setlinfo.value("fund_pay_sumamt").toDouble()) + "',"
                 "'" + QString::asprintf("%.2f",ret2207setlinfo.value("acct_pay").toDouble()) + "',"
                 "'" + QString::asprintf("%.2f",ret2207setlinfo.value("acct_mulaid_pay").toDouble()) + "',"

                 "'" + ret2207setlinfo.value("psn_type").toString() + "',"

                 "'" + personInsuinfo.value("insuplc_admdvs").toString()
                 + "','" + personBaseinfo.value("psn_no").toString()

                 + "','" + patientInfo["mdtrt_id"]
                 + "','" + patientInfo["ipt_otp_no"]
                 + "','" + msgid2207
                 + "','" + ret2207setlinfo.value("setl_id").toString()
                 + "','" + mdtrt_cert_type
                 + "','1',:Inpatient_No,:Balance_No,:Invoice_No,'11','',"
                   ":Card_No,:Mcard_No,'0','',To_Date('0001/1/1', 'YYYY-MM-DD'),'',"
                   ":Name,:Sex_Code,:Idenno,'',:Birthday,'','','',"
                   ":Dept_Code,:Dept_Name,:Paykind_Code,:Pact_Code,:Pact_Name,'',sysdate,"
                   "sysdate,'','',:Oper_Code,sysdate,:Reg_No,0,0,"
                   ":Year_Cost,sysdate,:Out_Diagnose,:Out_Diagnosename,"
                   "To_Date('0001/1/1', 'yyyy-mm-dd'),:Tot_Cost,:Pay_Cost,"
                   ":Pub_Cost,:Item_Paycost,:Base_Cost,:Item_Ylcost,:Item_Paycost2,"
                   ":Own_Cost, 0, '1', '1',:Remark,'0','1',:Person_Type,'','','','','',"
                   "'0','',0,0,0,:individualbalance)"
            );


    //qro->bindValue(":trans_type",mpPerson["trans_type"]);//交易类型，1正2负
    qro_tmp->bindValue(":Inpatient_No",patientInfo["CLINIC_CODE"]);//住院流水号,clinic_code
    qro_tmp->bindValue(":Balance_No", balanceNo);//结算序号
    qro_tmp->bindValue(":Invoice_No", invo_no);//发票号
    qro_tmp->bindValue(":Card_No", patientInfo["CARD_NO"]);//就诊卡号
    qro_tmp->bindValue(":Mcard_No", patientInfo["MCARD_NO"]);//医疗证号
    qro_tmp->bindValue(":Name", patientInfo["PATIENT_NAME"]);//姓名
    qro_tmp->bindValue(":Sex_Code",  patientInfo["SEX_CODE"]); //性别
    qro_tmp->bindValue(":Idenno", patientInfo["IDENNO"]);//身份证号

    QDateTime dt = QDateTime::fromString(patientInfo["BIRTHDAY"],"yyyy-MM-dd") ;
    qro_tmp->bindValue(":Birthday", dt);

    //qro->bindValue(":Birthday", QDate::fromString(patientInfo["BIRTHDAY"],"yyyyMMdd"));//生日
    qro_tmp->bindValue(":Dept_Code", patientInfo["Dept_Code"]);//科室代码
    qro_tmp->bindValue(":Dept_Name", patientInfo["Dept_Name"]); //科室名称
    qro_tmp->bindValue(":Paykind_Code", patientInfo["PAYKIND_CODE"]);//结算类别 1-自费  2-保险
    qro_tmp->bindValue(":Pact_Code", patientInfo["PACT_CODE"]); //合同代码
    qro_tmp->bindValue(":Pact_Name", patientInfo["PACT_NAME"]);//合同单位名称
    qro_tmp->bindValue(":Oper_Code", pub::usr_code);//操作员
    qro_tmp->bindValue(":Reg_No", patientInfo["regNo"]);//社保卡号
    qro_tmp->bindValue(":Year_Cost",0);
    qro_tmp->bindValue(":Out_Diagnose", patientInfo["Out_Diagnose"]);
    qro_tmp->bindValue(":Out_Diagnosename", patientInfo["Out_Diagnosename"]);
    qro_tmp->bindValue(":Tot_Cost", ybRet["Tot_Cost"]);//合计金额
    qro_tmp->bindValue(":Pay_Cost", ybRet["Pay_Cost"]); //账户支付
    qro_tmp->bindValue(":Pub_Cost", ybRet["Pub_Cost"]); //统筹支付
    qro_tmp->bindValue(":Own_Cost", ybRet["Own_Cost"]); //个人支付
    qro_tmp->bindValue(":Item_Ylcost", ybRet["Item_Ylcost"]);//乙类
    qro_tmp->bindValue(":Remark", patientInfo["remark"] );//险种类别2100返回
    qro_tmp->bindValue(":Person_Type", patientInfo["personType"]);//医疗待遇类别2100返回
    qro_tmp->bindValue(":individualbalance", ybRet["afterPay"]);


    if(!qro_tmp->exec())
    {
        QMessageBox::information(this,"错误","插入 fin_ipr_siinmaininfo 失败！");
        qDebug()<<qro_tmp->lastError().text();
        return false;
    }

    return true;
}

bool Form_sk::busi_2205()
{
    qDebug()<<"2205,撤销费用明细上传\n";

    //预结算不分发票只算总数，医保结算时需要按每张发票计算，所以要清除数据重新上传。

    QJsonObject in,inpu,inpud;
    QJsonDocument indoc;
    putBaseIn(  in, "2205");

    inpu.insert("mdtrt_id", patientInfo["mdtrt_id"]);   //就诊ID
    inpu.insert("chrg_bchno", "0000");   //传“0000”，删除所有未结算数据
    inpu.insert("psn_no", personBaseinfo.value("psn_no").toString());//

    inpud.insert("data",inpu);
    in.insert("input", inpud);
    indoc.setObject(in);
    //保存入参日志
    sq = "update com_business set v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }

    QNetworkReply* reply = manager.post(request,indoc.toJson());
    QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " http 请求状态错误: " + statusCode.toString());
        return false;
    }

    QNetworkReply::NetworkError err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false;
    }

    QByteArray btret = reply->readAll();
    QString t = QString::fromLocal8Bit(btret);

    QJsonParseError json_error;

    QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意", currentInfno + " 返回信息解析错误 " + json_error.errorString());
        return false;
    }

    QJsonObject jsob = jsdc.object();

    //保存出出参日志
    QString out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set tmstmp = now(), v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +  "  where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }

    qDebug()<<"2205 结束\n";

    return true;
}

bool Form_sk::calc_store_num()
{
    //计算库存是否充足
    sq = " select base.t_qty , " //当前处方数量（最小单位）
         " info.recal ," //挂账数量（计价单位）
         " pack_qty, " //包装数量
         " base.store_sum, " //库存数量（最小单位）
         " base.item_name" //项目名称
         " from"
         "   (SELECT"
         "     SUM (f.qty * f.pack_qty) t_qty,"
         "     f.item_name,"
         "     f.item_code,"
         "     s.store_sum,"
         "     f.pack_qty"
         "   FROM"
         "     met_ord_recipedetail f," //中间处方
         "     pha_com_stockinfo s" //库存
         "   WHERE"
         "     f.drug_flag IN ('1', '4')" //西药中成药，草药
         "     AND f.item_code = s.drug_code"
         "     AND f.phamarcy_code = s.drug_dept_code"
         "     AND f.status <> '4'" //未作废
         "     AND f.charge_flag = '0'" //未收费
         "     AND f.clinic_code = '%1'"
         "   GROUP BY"
         "     f.item_name,"
         "     f.item_code,"
         "     s.store_sum,"
         "     f.pack_qty"
         "   ) base "
         " left join drug_base_info info "
         "     on info.drug_code = base.item_code";

    sq = sq.arg(patientInfo["CLINIC_CODE"]);

    qDebug()<<"计算库存是否充足 : "<<sq<<"\n";

    qro->exec(sq);

    //是否存在申请数量是否超过库存数量的记录
    while(qro->next())
    {
        int recipe_qty = qro->value("t_qty").toInt();
        int recal = qro->value("recal").toInt();
        int pack_qty = qro->value("pack_qty").toInt();
        int store_sum = qro->value("store_sum").toInt();
        QString item_name = qro->value("item_name").toString();

        if(recipe_qty + recal * pack_qty > store_sum)
        {
            QMessageBox::information(this,"注意", item_name + " 申请数量大于库存数量，处方无法执行！");
            return false;
        }
    }
    return true;
}

bool Form_sk::calc_fee_type()
{
    //计算发票收费分类, 分类方法：开单科室 + 费用类别
    QMap<QString,QString> mp;   //list 公用变量

    qDebug()<<"计算发票收费分类";
    sq = " select "
         "   (select fee_stat_name from FIN_COM_FEECODESTAT "
         "    where rownum = '1' and report_code='MZ01' and fee_code = f.fee_code) fee_name, "
         " fee_code, exec_dpcd, exec_dpnm, sum(own_cost) own_cost "
         " from met_ord_recipedetail f "
         " where clinic_code = '"
         + patientInfo["CLINIC_CODE"]
         + "' and status <> '4' and charge_flag = '0'"
         " group by exec_dpcd, fee_code, exec_dpnm order by exec_dpcd,fee_code";
    qDebug()<<sq<<"\n";
    qro->exec(sq);

    lstFeeType.clear();

    double countFeeList = 0;   //对金额进行累计

    while(qro->next())
    {
        mp["fee_name"] = qro->value("fee_name").toString();
        mp["fee_code"] = qro->value("fee_code").toString();
        mp["dept_code"] = qro->value("exec_dpcd").toString();
        mp["dept_name"] = qro->value("exec_dpnm").toString();
        mp["own_cost"] = QString::asprintf("%.2f", qro->value("own_cost").toDouble());
        mp["invoice_no"] = "invoice_no";
        countFeeList += qro->value("own_cost").toDouble();
        lstFeeType << mp;
    }

    qDebug()<<"lstFeeType : "<<lstFeeType<<"\n";
    mp.clear();

    double countItemDetail = 0;   //对 lstItemDetail 金额进行累计
    qDebug()<<"lstItemDetail is " <<lstItemDetail;

    foreach(mp, lstItemDetail)
    {
        countItemDetail += double( qRound( 100 * mp["RETAIL_PRICE"].toDouble()
                * mp["APPLY_NUM"].toDouble()
                / mp["PACK_QTY"].toDouble()))
                / 100 ;
    }

    if( !qFuzzyCompare(countFeeList, countItemDetail))
    {
        //前后结果不相等
        QMessageBox::information(this,"注意", " 汇总金额（"
                                 + QString::number(countItemDetail) +
                                 "）与明细金额（"
                                 + QString::number(countFeeList) +
                                 "）累计不符！");
        qDebug()<<"countFeeList is "<<QString::number(countFeeList)
               <<", countItemDetail is "<<QString::number(countItemDetail);
        return false;
    }

    return true;
}

bool Form_sk::calc_invoice(QSqlQuery *qro_tmp)
{
    QString execDeptCode = "";
    QString invoice_no, invoice_seq;
    //invoices = "'invoice'";    //便于算法书写，预置一个不可能存在的发票号
    //QSqlQuery *qro_tmp = new QSqlQuery(pub::db_o);
    QMap<QString,QString> mp;   //list 公用变量
    int idx = 0;

    //申请发票号，写入 fin_opb_invoicedetail
    foreach(mp, lstFeeType)
    {
        //执行科室变更，申请新发票号
        if(execDeptCode != mp["dept_code"])
        {
            execDeptCode = mp["dept_code"];

            char errorText[128];
            for(int i = 0; i<128; i++)
            {
                errorText[i] = '0';
            }

            char fpChar[12];
            for(int i = 0; i<12; i++)
            {
                fpChar[i] = '0';
            }

            int errorCode = 0;
            QString a,b,c;

            qro_tmp->prepare("call prc_get_invoiceno('C', :oper, 50, :ivno, :errtext, :errcode, '')");
            qro_tmp->bindValue(":oper", pub::usr_code );//操作员Id
            qro_tmp->bindValue(":ivno", fpChar, QSql::Out);   //发票号码
            qro_tmp->bindValue(":errtext", errorText, QSql::Out);   //错误内容
            qro_tmp->bindValue(":errcode", errorCode, QSql::Out);    //错误编号
            qro_tmp->exec();

            a = qro_tmp->boundValue(":ivno").toString();
            b = qro_tmp->boundValue(":errtext").toString();
            c = qro_tmp->boundValue(":errcode").toString();

            if( a.isEmpty())
            {
                QMessageBox::information(this,"错误", "申请发票号失败：" + b );
                return false;
            }

            if(c == "101"){
                QMessageBox::information(this,"注意", "未用发票数量低，请及时请领！" );
            }

            invoice_no = a;//发票号
            //invoices = invoices + ",'" + a + "'";
            invoice_list << invoice_no;

            qro_tmp->exec("select seq_fin_opb_invoice.nextval from dual");
            qro_tmp->next();
            invoice_seq = qro_tmp->value(0).toString();
            if(invoice_seq.isEmpty())
            {
                QMessageBox::information(this,"注意", "seq_fin_opb_invoice.nextval 返回失败！" );
                return false;
            }
        }

        //发票明细表(费用分类表)
        sq = "Insert into fin_opb_invoicedetail "
             "(INVOICE_NO,TRANS_TYPE,INVO_CODE,INVO_SEQUENCE,INVO_NAME,PUB_COST,"
             "OWN_COST,PAY_COST,DEPT_CODE,DEPT_NAME,OPER_DATE,"
             "OPER_CODE,BALANCE_FLAG,BALANCE_NO,BALANCE_OPCD,"
             "BALANCE_DATE,CANCEL_FLAG,INVOICE_SEQ)"
             " Values"
             " ('%1','1','%2','%3','%4',0,"
             " %5,0,'%6','%7',sysdate, '%8','0','','',"
             " to_date('0001/1/1','yyyy-mm-dd'),'1','%9')  ";
        sq = sq.arg(invoice_no)
                .arg(mp["fee_code"].right(2))
                .arg(QString::number(idx))
                .arg(mp["fee_name"])
                .arg(mp["own_cost"])
                .arg(mp["dept_code"])
                .arg(mp["dept_name"])
                .arg(pub::usr_code)
                .arg(invoice_seq);
        qDebug()<<"保存发票明细表(费用分类表)"<<sq<<"\n";
        lstFeeType[idx]["invoice_no"] = invoice_no; //补齐发票号，为后续算法方便
        idx ++;

        pub::db_o.exec(sq);

        if(pub::db_o.lastError().isValid())
        {
            QMessageBox::information(this,"注意", "插入 fin_opb_invoicedetail 失败！");
            qDebug()<<invoice_no<<mp["fee_code"].right(2)<< mp["fee_name"]<<mp["dept_code"]<<mp["dept_name"]
                   <<mp["own_cost"]<<pub::usr_code<<invoice_seq;
            qDebug()<<pub::db_o.lastError().text();
            return false;
        }

    }

    return true;
}

bool Form_sk::save_invoice_to_list(QSqlQuery *qro_tmp)
{
    qDebug()<<"保存发票信息到 list \n";
    QMap<QString,QString> mp;

    lstInvoiceInfo.clear();

    //患者一次结算产生多张发票，使用同一个 BALANCE_COMBONO
    qro_tmp->exec("select seq_fin_opb_balancecombono.nextval from dual");
    qro_tmp->next();
    patientInfo["BALANCE_COMBONO"] = qro_tmp->value(0).toString();

    sq = "select invoice_no, invoice_seq, dept_name, sum(own_cost) ocst, dept_code ,"
         " (select ext_flag from com_department dept where dept.dept_code = fin.dept_code) "//dept_code "
         " from fin_opb_invoicedetail fin "
         " where invoice_no in('%1') group by invoice_no, invoice_seq, dept_name,dept_code";
    sq = sq.arg(invoice_list.join("','"));

    qDebug()<<sq<<"\n";


    if(!qro_tmp->exec(sq))
    {
        QMessageBox::information(this,"注意", "提取 fin_opb_invoicedetail 失败！");
        return false;
    }

    while(qro_tmp->next())
    {
        mp["invoice_no"] = qro_tmp->value(0).toString();
        mp["invoice_seq"] = qro_tmp->value(1).toString();
        mp["dept_name"] = qro_tmp->value(2).toString();
        mp["ocst"] = QString::asprintf("%.2f",qro_tmp->value(3).toDouble());
        mp["dept_code"] = qro_tmp->value(4).toString();
        mp["printItem"] = qro_tmp->value(5).toString();;

        //根据执行科室为 lstItemDetail 补齐发票号内容
        //bool hasInsu;   //有医保项目
        mp["has_insu"] = "0";  //预置发票无医保内容
        for(int id = 0; id<lstItemDetail.length(); id ++)
        {
            if(lstItemDetail[id]["DRUG_DEPT_CODE"] == mp["dept_code"])
            {
                lstItemDetail[id]["invoice_no"] = mp["invoice_no"];
                lstItemDetail[id]["invoice_seq"] = mp["invoice_seq"];
                if(lstItemDetail[id]["has_compare"] == "1")
                {
                    mp["has_insu"] = "1";//此发票有医保内容
                }
            }
        }

        //按现金操作预置
        mp["real_cost"] = mp["ocst"];
        mp["own_cost"] = mp["ocst"];
        mp["tot_cost"] = mp["ocst"];
        mp["pay_cost"] = "";
        mp["gjzf"] = "";
        //
        lstInvoiceInfo << mp;

    }

    qDebug()<<"lstInvoiceInfo : "<<lstInvoiceInfo<<"\n";

    return true;
}

void Form_sk::restore_invoice()
{
    //
    qDebug()<<"恢复发票信息\n";

    int max_idx = invoice_list.size() - 1 ;
    if(max_idx < 0)
    {
        qDebug()<<"发票号列表为空！\n";
        return;
    }

    QString iv_start = invoice_list[0];
    qDebug()<<"current iv_start is "<<iv_start<<"\n";

    sq = "select start_no, end_no from fin_com_invoice "
         " where get_person_code = '%1' and used_state = '1' and invoice_kind = 'C' ";
    sq = sq.arg(pub::usr_code);
    qDebug()<<"提取发票使用记录："<<sq<<"\n";
    qro->exec(sq);

    if(!qro->next())
    {
        qDebug()<<"提取发票使用记录结果为空\n";
        return;
    }

    QString str_start = qro->value(0).toString();
    QString str_end = qro->value(1).toString();
    int start = str_start.toInt();
    int end = str_end.toInt();
    int cur = iv_start.toInt();
    qDebug()<<"在用发票号段为： "<<str_start<<" - "<<str_end<<"\n";

    //如本次申请的号码在当前使用范围内，进行恢复。
    if(start < cur && cur < end)
    {
        //本次申请前的最后一个号码
        cur = cur - 1;

        QString str_cur = pub::add0(QString::number(cur),12);

        sq = " update fin_com_invoice set used_no = '%1' "
             " where get_person_code = '%2' and used_state = '1' and invoice_kind = 'C' "
             " and start_no = '%3' and end_no = '%4'";
        sq = sq.arg(str_cur).arg(pub::usr_code).arg(str_start).arg(str_end);

        qDebug()<<"恢复本次申请前的发票使用状态："<<sq<<"\n";

        qDebug()<<"restore iv_start to "<<str_cur<<"\n";

        if(!qro->exec(sq))
        {
            qDebug()<<qro->lastError().text();
            return;
        }
    }
}

bool Form_sk::process_SI(QSqlQuery * qro_tmp)
{
    QMap<QString,QString> mp;

    if( patientInfo["yb"] != "1")
    {
        return true;
    }

    //本次操作是医保结算, 保存医保相关数据
    tmString = "进行医保结算数据";
    ui->lbMode->setText(tmString);
    qApp->processEvents();  //刷新显示

    foreach ( mp, lstInvoiceInfo )
    {
        if(mp["has_insu"] == "0")
        {
            //此发票无医保内容
            continue;
        }
        patientInfo["Dept_Code"] = mp["dept_code"]; //saveSi需要此值
        patientInfo["Dept_Name"] = mp["dept_name"]; //saveSi需要此值
        if(!saveSI(mp["invoice_no"], qro_tmp))
        {
            //保存医保信息失败
            return  false;
        }
    }

    return  true;
}

bool Form_sk::process_invo_info(QSqlQuery * qro_tmp)
{
    QMap<QString,QString> mp;   //list 公用变量

    //发票信息表(结算信息表)
    qDebug()<<"发票信息表(结算信息表)";
    int printInvoiceno = 0;

    int idx = 0;
    ui->lbMode->setText("保存发票信息");
    qApp->processEvents();  //刷新显示

    foreach(mp, lstInvoiceInfo)
    {

        //涉及到现金四舍五入，全都进行记录。多张发票四舍五入结果相互调剂
        //通过POS机支付的现金不需要四舍五入

        //预置实付为应付
        double real_pay_45 = mp["own_cost"].toDouble();

        if(balanceFlag)
        {
            //需要四舍五入
            double t = mp["own_cost"].toDouble();
            double t45 = QString::asprintf("%.1f",t).toDouble();
            if( !qFuzzyCompare(t, t45)){       //四舍五入前后结果不相等，进行补偿计算
                t = t + balance;    //对每张发票的差额进行累计补偿
                t45 = QString::asprintf("%.1f",t).toDouble();   //累计之后的本张发票实收额
                balance = t - t45;  //新的累计差额
            }
            //qro->bindValue(":REAL_COST", t45);

            sq = "Insert into fin_opb_paymode"
                 "(INVOICE_NO,TRANS_TYPE,SEQUENCE_NO,MODE_CODE,TOT_COST,REAL_COST, OPER_CODE,"
                 "OPER_DATE,CHECK_FLAG,CHECK_OPCD,BALANCE_FLAG,BALANCE_NO,BALANCE_OPCD,CORRECT_FLAG,"
                 " CORRECT_OPCD,INVOICE_SEQ,CANCEL_FLAG,postrans_no ,MEMO,balance_combono )"
                 " Values "
                 "('%1','1','%2','CA',%3, %4, '%5',sysdate,'0',"
                 "'','0','','','0','','%6','1','' ,'','%7')";
            sq = sq.arg(mp["invoice_no"])
                    .arg(QString::number(balanceSeq))
                    .arg(mp["ocst"])
                    .arg(t45)
                    .arg(pub::usr_code)
                    .arg(mp["invoice_seq"])
                    .arg(patientInfo["BALANCE_COMBONO"]);


            //实付发生四舍五入
            real_pay_45 = t45;
            qDebug()<<"保存四舍五入数据:"<<sq<<"\n";

            pub::db_o.exec(sq);
            if(pub::db_o.lastError().isValid())
            {
                QMessageBox::information(this,"错误","保存四舍五入数据失败！");
                qDebug()<<pub::db_o.lastError().text()<<"\n";
                return false;
            }

            lstInvoiceInfo[idx]["real_cost"] = QString::asprintf("%.1f", t45);
            balanceSeq ++;
        }

        sq = "Insert into fin_opb_invoiceinfo"
             " (INVOICE_NO,TRANS_TYPE,CARD_NO,REG_DATE,NAME,PAYKIND_CODE,"
             " PACT_CODE,PACT_NAME,MCARD_NO,MEDICAL_TYPE,TOT_COST,PUB_COST,OWN_COST,"
             " PAY_COST,BACK1,BACK2,BACK3,REAL_COST,OPER_CODE,"
             " OPER_DATE,EXAMINE_FLAG,CANCEL_FLAG,CHECK_FLAG,BALANCE_FLAG,"
             " INVOICE_SEQ,CLINIC_CODE,PRINT_INVOICENO,DRUG_WINDOW,"
             " ACCOUNT_FLAG,BALANCE_COMBONO)"
             " Values("
             " '%1','1','%2',to_date('%3','yyyy-mm-dd hh24:mi:ss'),"//:INVOICE_NO,:CARD_NO,:REG_DATE
                " '%4','%5',"//:NAME,:PAYKIND_CODE
                " '%6','%7','%8','%9',"//:PACT_CODE,:PACT_NAME,:MCARD_NO,:MEDICAL_TYPE
                " '%10','%11','%12',"//:TOT_COST,:PUB_COST,:OWN_COST
                " '%13','0','','','%14','%15', sysdate,'0','1','0','0',"//:PAY_COST:real_cost,:OPER_CODE,
                " '%16','%17','%18',"//:INVOICE_SEQ,:CLINIC_CODE,:PRINT_INVOICENO,"
                " '%19','0','%20')";//:DRUG_WINDOW,:BALANCE_COMBONO
        sq = sq.arg(mp["invoice_no"]);//qro->bindValue(":INVOICE_NO", );
        sq = sq.arg(patientInfo["CARD_NO"]);//qro->bindValue(":CARD_NO", );
        sq = sq.arg(patientInfo["REG_DATE"]);//QDateTime dt = QDateTime::fromString(,"yyyy-MM-dd hh:mm:ss") ;
        //qro->bindValue(":REG_DATE", dt);

        sq = sq.arg(patientInfo["PATIENT_NAME"]);//qro->bindValue(":NAME", );
        sq = sq.arg(patientInfo["PAYKIND_CODE"]);//qro->bindValue(":PAYKIND_CODE", );

        sq = sq.arg(patientInfo["PACT_CODE"]);//qro->bindValue(":PACT_CODE", );
        sq = sq.arg(patientInfo["PACT_NAME"]);//qro->bindValue(":PACT_NAME", );
        sq = sq.arg(patientInfo["MCARD_NO"]);//qro->bindValue(":MCARD_NO", );
        sq = sq.arg(patientInfo["MEDICAL_TYPE"]);//qro->bindValue(":MEDICAL_TYPE", );

        sq = sq.arg(mp["ocst"]);//qro->bindValue(":TOT_COST", );
        sq = sq.arg(mp["pub_cost"]);//qro->bindValue(":PUB_COST", );
        sq = sq.arg(mp["own_cost"]);//qro->bindValue(":OWN_COST", );

        sq = sq.arg(mp["pay_cost"]);//qro->bindValue(":PAY_COST", );
        sq = sq.arg(real_pay_45);//qro->bindValue(":real_cost" , );
        sq = sq.arg(pub::usr_code);//qro->bindValue(":OPER_CODE", );

        sq = sq.arg(mp["invoice_seq"]);//qro->bindValue(":INVOICE_SEQ", );
        sq = sq.arg(patientInfo["CLINIC_CODE"]);//qro->bindValue(":CLINIC_CODE",);
        sq = sq.arg(QString::number(printInvoiceno));//qro->bindValue(":PRINT_INVOICENO", );

        sq = sq.arg(mp["dept_name"]);//qro->bindValue(":DRUG_WINDOW", );
        sq = sq.arg(patientInfo["BALANCE_COMBONO"]);//qro->bindValue(":BALANCE_COMBONO",);

        qDebug()<<"插入 fin_opb_invoiceinfo : "<<sq<<"\n";

        pub::db_o.exec(sq);
        if(pub::db_o.lastError().isValid())
        {
            QMessageBox::information(this,"错误","插入 fin_opb_invoiceinfo 失败！");
            qDebug()<<pub::db_o.lastError().text()<<"\n";
            return false;
        }

        idx++;
        printInvoiceno ++;
    }

    //保存当前工作发票号
    sq = " update COM_DICTIONARY set name='%1', mark='%2', oper_Date = sysdate "
         " where type ='MZINVOICE' and code ='%3'";
    sq = sq.arg(QString::number(printInvoiceno)).arg(mp["invoice_no"]).arg(pub::usr_code);
    qDebug()<<"保存当前工作发票号 : "<<sq<<"\n";

    pub::db_o.exec(sq);
    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","保存当前工作发票号 失败！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    return true;
}

bool Form_sk::save_feedetail(QSqlQuery * qro_tmp)
{
    qDebug()<<"写入pha_com_applyout, 补全 fin_opb_feedetail, met_ord_recipedetail";

    //bool stop = false;   //循环结束之后的退出标志
    QMap<QString,QString> mp;

    ui->lbMode->setText("保存收费明细");
    qApp->processEvents();  //刷新显示

    int idx = 0;       //循环索引，控制循环结束使用
    applyNumbers = "0";    //保存写入到pha_com_applyout中的 apply_number

    foreach(mp, lstItemDetail)
    {
        idx ++;
        //写入 fin_opb_feedetail 数据
        ui->lbMode->setText("保存收费明细-fin_opb_feedetail");
        qApp->processEvents();  //刷新显示

        qDebug()<<"写入 fin_opb_feedetail 数据";
        sq = "update fin_opb_feedetail set ";
        //sq += " center_code = '" + mp["center_code"] + "',";
        //sq += " item_grade = '" + mp["center_item_grade"] + "',";
        sq += " pay_flag = '1', ";
        //sq += " fee_cpcd = '" + mp["DEPT_CODE"] + "',";
        sq += " fee_cpcd = '" + pub::usr_code + "',";
        sq += " fee_date = sysdate, ";
        sq += " invoice_no = '" + mp["invoice_no"] + "',";
        sq += " invoice_seq = '" + mp["invoice_seq"] + "',";
        sq += " new_itemrate = '" + mp["center_rate"] + "',";
        if(patientInfo["yb"] == "1" ){ //医保交易和现金交易此字段值有区别
            sq += " old_itemrate = '0',";
        }else{
            sq += " old_itemrate = '1',";
        }
        sq += " ext_flag = '1', ";
        sq += " over_cost = unit_price ";
        sq += " where pay_flag = '0' ";
        sq += " and clinic_code = '" + patientInfo["CLINIC_CODE"] + "' ";
        sq += " and item_code = '" + mp["item_code"] + "' ";
        sq += " and recipe_no = '" + mp["RECIPE_NO"] + "' ";

        qDebug()<<"保存收费明细-fin_opb_feedetail : "<<sq<<"\n";

        pub::db_o.exec(sq);
        if(pub::db_o.lastError().isValid())
        {
            QMessageBox::information(this,"错误","保存收费明细-fin_opb_feedetail 失败！");
            qDebug()<<pub::db_o.lastError().text()<<"\n";
            return false;
        }

        ui->lbMode->setText("保存收费明细-met_ord_recipedetail");
        qApp->processEvents();

        sq = "update met_ord_recipedetail set charge_flag ='1' , status ='1' ,"
             " charge_code = '%1', charge_date = sysdate"
             " where sequence_no = '%2' and status='0'";
        sq = sq.arg(pub::usr_code).arg(mp["MO_ORDER"]);
        qDebug()<<"写入 met_ord_recipedetail 数据"<<sq<<"\n";

        pub::db_o.exec(sq);
        if(pub::db_o.lastError().isValid())
        {
            QMessageBox::information(this,"错误","写入 met_ord_recipedetail 失败！");
            qDebug()<<pub::db_o.lastError().text()<<"\n";
            return false;
        }

        //如果项目不是药品，跳过写入 pha_com_applyout 过程

        if(mp["drug_flag"] != "1" && mp["drug_flag"] != "4")
        {
            //从 met_ord_recipedetail 提取
            qDebug()<<mp["TRADE_NAME"] <<" ： 非药品";
            continue;
        }

        qro_tmp->exec("select seq_pha_applyout_id.nextval from dual");
        qro_tmp->next();
        QString apply_num = qro_tmp->value(0).toString();
        applyNumbers.append("," + apply_num );
        ui->lbMode->setText("保存收费明细-pha_com_applyout");
        qApp->processEvents();

        sq = "INSERT INTO PHA_COM_APPLYOUT (APPLY_NUMBER ,DEPT_CODE ,DRUG_DEPT_CODE ,"
             "CLASS3_MEANING_CODE , GROUP_CODE ,DRUG_CODE ,TRADE_NAME ,BATCH_NO ,"
             "DRUG_TYPE ,DRUG_QUALITY, SPECS , PACK_UNIT , PACK_QTY , MIN_UNIT , "
             "SHOW_FLAG , SHOW_UNIT , RETAIL_PRICE ,WHOLESALE_PRICE ,PURCHASE_PRICE ,"
             "APPLY_OPERCODE ,APPLY_DATE ,APPLY_STATE , APPLY_NUM ,DAYS ,"
             "PREOUT_FLAG ,CHARGE_FLAG ,PATIENT_ID ,PATIENT_DEPT ,DOSE_ONCE ,"
             "DOSE_UNIT ,USAGE_CODE ,USE_NAME ,DFQ_FREQ ,DFQ_CEXP ,DOSE_MODEL_CODE,"
             "MO_ORDER ,COMB_NO  , RECIPE_NO ,SEQUENCE_NO,SEND_TYPE,BILLCLASS_CODE,"
             "PRINT_STATE,OUT_BILL_CODE,VALID_STATE,MARK,PLACE_CODE) "
             " VALUES ("
             " %1, '%2' ,'%3' ,'M1' , '0' ,'%4' ,"//:apply_num, :DEPT_CODE ,:DRUG_DEPT_CODE ,'M1' , '0' ,:DRUG_CODE ,
             " '%5', '', '%6', '%7',"//:TRADE_NAME ,'' ,:DRUG_TYPE ,:DRUG_QUALITY,
             " '%8' , '%9' , '%10' ," //:SPECS , :PACK_UNIT ,:PACK_QTY ,
             " '%11' , '0' , '', %12 ,0 ,0 , '%13' ,sysdate ,'0' ,"//:MIN_UNIT, :RETAIL_PRICE, :APPLY_OPERCODE
             " %14 ,%15 ,'0' ,'1' ,'%16','%17','%18' ,"//:APPLY_NUM,:DAYS,:PATIENT_ID ,:PATIENT_DEPT ,:DOSE_ONCE
             " '%19','%20','%21','%22',"//:DOSE_UNIT ,:USAGE_CODE , :USE_NAME ,:DFQ_FREQ ,
             "(select frequency_name from MET_COM_DEPTFREQUENCY "
             " where rownum = '1' and frequency_code = :DFQ_FREQ ),'%23','%24',"//:DOSE_MODEL_CODE,:MO_ORDER
             " '%25' , '%26' ,'%27','0','','',0,'1','','') ";//:COMB_NO , :RECIPE_NO ,:SEQUENCE_NO

        sq = sq.arg(apply_num);//qro_tmp->bindValue(":apply_num",  );
        sq = sq.arg(mp["DEPT_CODE"]);//qro_tmp->bindValue(":DEPT_CODE",  );
        sq = sq.arg(mp["phamarcy_code"]);//qro_tmp->bindValue(":DRUG_DEPT_CODE",  );
        sq = sq.arg(mp["item_code"]);//qro_tmp->bindValue(":DRUG_CODE",  );

        sq = sq.arg(mp["TRADE_NAME"]);//qro_tmp->bindValue(":TRADE_NAME", mp[""] );
        sq = sq.arg(mp["DRUG_TYPE"]);//qro_tmp->bindValue(":DRUG_TYPE", mp[""] );
        sq = sq.arg(mp["DRUG_QUALITY"]);//qro_tmp->bindValue(":DRUG_QUALITY", mp[""] );

        sq = sq.arg(mp["SPECS"]);//qro_tmp->bindValue(":SPECS", mp[""] );
        sq = sq.arg(mp["PACK_UNIT"]);//qro_tmp->bindValue(":PACK_UNIT", mp[""] );
        sq = sq.arg(mp["PACK_QTY"]);//qro_tmp->bindValue(":PACK_QTY", mp[""] );

        sq = sq.arg(mp["MIN_UNIT"]);//qro_tmp->bindValue(":MIN_UNIT", mp[""] );
        sq = sq.arg(mp["RETAIL_PRICE"]);//qro_tmp->bindValue(":RETAIL_PRICE", mp[""] );
        sq = sq.arg(pub::usr_code);//qro_tmp->bindValue(":APPLY_OPERCODE",e);

        sq = sq.arg(mp["APPLY_NUM"]);//qro_tmp->bindValue(":APPLY_NUM", mp[""] );
        sq = sq.arg(mp["DAYS"]);//qro_tmp->bindValue(":DAYS", mp[""] );
        sq = sq.arg(mp["PATIENT_ID"]);//qro_tmp->bindValue(":PATIENT_ID", mp[""] );
        sq = sq.arg(mp["PATIENT_DEPT"]);//qro_tmp->bindValue(":PATIENT_DEPT", mp[""] );
        sq = sq.arg(mp["DOSE_ONCE"]);//qro_tmp->bindValue(":DOSE_ONCE", mp[""] );

        sq = sq.arg(mp["DOSE_UNIT"]);//qro_tmp->bindValue(":DOSE_UNIT", mp[""] );
        sq = sq.arg(mp["USAGE_CODE"]);//qro_tmp->bindValue(":USAGE_CODE", mp[""] );
        sq = sq.arg(mp["USE_NAME"]);//qro_tmp->bindValue(":USE_NAME", mp[""] );
        sq = sq.arg(mp["DFQ_FREQ"]);//qro_tmp->bindValue(":DFQ_FREQ", mp[""] );

        sq = sq.arg(mp["DOSE_MODEL_CODE"]);//qro_tmp->bindValue(":DOSE_MODEL_CODE", mp[""] );
        sq = sq.arg(mp["MO_ORDER"]);//qro_tmp->bindValue(":MO_ORDER", mp[""] );

        sq = sq.arg(mp["COMB_NO"]);//qro_tmp->bindValue(":COMB_NO", mp[""] );
        sq = sq.arg(mp["RECIPE_NO"]);//qro_tmp->bindValue(":RECIPE_NO", mp[""] );
        sq = sq.arg(mp["SEQUENCE_NO"]);//qro_tmp->bindValue(":SEQUENCE_NO", mp[""] );

        qDebug()<<"写入 pha_com_applyout : "<<sq<<"\n";

        pub::db_o.exec(sq);
        if(pub::db_o.lastError().isValid())
        {
            QMessageBox::information(this,"错误","写入 pha_com_applyout 失败！");
            qDebug()<<pub::db_o.lastError().text()<<"\n";
            return false;
        }
    }

    return true;
}

bool Form_sk::save_recipe(QSqlQuery * qro_tmp)
{
    qDebug()<<"保存处方信息\n";

    QMap<QString, QString> mp;

    ui->lbMode->setText("保存处方信息");
    qApp->processEvents();  //刷新显示

    sq = " select recipe_no, drug_dept_code, dept_code, count(recipe_no), "//0-3
         " sum(apply_num * retail_price / pack_qty)"//4
         " from pha_com_applyout "
         " where apply_number in(%1) group by recipe_no,drug_dept_code,dept_code";
    sq = sq.arg(applyNumbers);

    qDebug()<<"从 pha_com_applyout 提取数据 "<<sq;
    if(!qro_tmp->exec(sq))
    {
        QMessageBox::information(this,"错误", "从 pha_com_applyout 提取数据失败！");
        qDebug()<<qro_tmp->lastQuery();
        return false;
    }

    QString doc_dpt, doc_cod, ivno;
    while(qro_tmp->next())
    {
        ivno = "";
        doc_dpt = "";
        doc_cod = "";
        foreach(mp, lstItemDetail)
        {
            //提取关联信息
            if( mp["RECIPE_NO"] ==  qro_tmp->value(0).toString()
                    && mp["phamarcy_code"] ==  qro_tmp->value(1).toString())
            {
                doc_cod = mp["doct_code"] ;
                doc_dpt = mp["doct_dept"] ;
                ivno = mp["invoice_no"];
                break;
            }
        }

        if(ivno.isEmpty())
        {
            QMessageBox::information(this,"错误", "写入 pha_sto_recipe 时提取发票号失败！");
            return false;
        }

        sq = "INSERT INTO PHA_STO_RECIPE "
             "(DRUG_DEPT_CODE, RECIPE_NO, CLASS3_MEANING_CODE, TRANS_TYPE, RECIPE_STATE,"
             "CLINIC_CODE, CARD_NO, PATIENT_NAME, SEX_CODE, BIRTHDAY, PAYKIND_CODE, DEPT_CODE,"
             "REG_DATE, DOCT_CODE, DOCT_DEPT, DRUGED_TERMINAL, SEND_TERMINAL, FEE_OPER, FEE_DATE,"
             "INVOICE_NO, RECIPE_COST, RECIPE_QTY, DRUGED_QTY, DRUGED_OPER, DRUGED_DEPT,"
             "DRUGED_DATE, SEND_DATE, SEND_DEPT, VALID_STATE, MODIFY_FLAG, MARK, SUM_DAYS )"
             " VALUES "
             "('%1','%2', 'M1', '1', '0', "//:DRUG_DEPT_CODE,:RECIPE_NO
             "'%3', '%4', '%5',"//:CLINIC_CODE, :CARD_NO, :PATIENT_NAME,
             "'%6', to_date('%7','yyyy-mm-dd'), '%8', '%9', "//:SEX_CODE, :BIRTHDAY, :PAYKIND_CODE, :DEPT_CODE,
             "to_date('%10','yyyy-mm-dd hh24:mi:ss'), '%11', '%12',"//:REG_DATE, :DOCT_CODE, :DOCT_DEPT,
             "(select t_code from pha_sto_terminal "
             "     where rownum = '1' and dept_code = '%1' and t_type = '1' ),"//:DRUG_DEPT_CODE
             "(select t_code from pha_sto_terminal "
             "     where rownum = '1' and dept_code = '%1' and t_type = '0' ), "//:DRUG_DEPT_CODE
             "'%13', sysdate, '%14', %15, %16,"//:FEE_OPER, sysdate, :INVOICE_NO, :RECIPE_COST, :RECIPE_QTY,
             " 0, '', '%1',"//:DRUGED_QTY, :DRUGED_OPER,:DRUG_DEPT_CODE
             " sysdate, sysdate, '%1', '1','0', 'c', 0 )";//:DRUG_DEPT_CODE,

        sq = sq.arg(qro_tmp->value(1).toString());//1,qro->bindValue(":DRUG_DEPT_CODE", );
        sq = sq.arg(qro_tmp->value(0).toString());//2,qro->bindValue(":RECIPE_NO", );

        sq = sq.arg(patientInfo["CLINIC_CODE"]);//3,qro->bindValue(":CLINIC_CODE", );
        sq = sq.arg(patientInfo["CARD_NO"]);//4,qro->bindValue(":CARD_NO", );
        sq = sq.arg(patientInfo["PATIENT_NAME"]);//5,qro->bindValue(":PATIENT_NAME", );

        sq = sq.arg(patientInfo["SEX_CODE"]);//6,qro->bindValue(":SEX_CODE", );
        sq = sq.arg(patientInfo["BIRTHDAY"]);//7,qro->bindValue(":BIRTHDAY", dt);
        sq = sq.arg(patientInfo["PAYKIND_CODE"]);//8,qro->bindValue(":PAYKIND_CODE", );
        sq = sq.arg(qro_tmp->value(2).toString());//9,qro->bindValue(":DEPT_CODE",  );

        sq = sq.arg(patientInfo["REG_DATE"]);//10,qro->bindValue(":REG_DATE", dt);
        sq = sq.arg(doc_cod);//11,qro->bindValue(":DOCT_CODE", );
        sq = sq.arg(doc_dpt);//12,qro->bindValue(":DOCT_DEPT", );

        sq = sq.arg(pub::usr_code);//13,qro->bindValue(":FEE_OPER", );
        sq = sq.arg(ivno);//14,qro->bindValue(":INVOICE_NO", );
        sq = sq.arg(qro_tmp->value(4).toString());//15,qro->bindValue(":RECIPE_COST", );
        sq = sq.arg(qro_tmp->value(3).toString());//16,qro->bindValue(":RECIPE_QTY",  );

        qDebug()<<"写入 PHA_STO_RECIPE 数据"<<sq<<"\n";
        pub::db_o.exec(sq);
        if(pub::db_o.lastError().isValid())
        {
            QMessageBox::information(this,"错误","写入 pha_com_applyout 失败！");
            qDebug()<<pub::db_o.lastError().text()<<"\n";
            return false;
        }
    }

    return true;
}

void Form_sk::on_pbSfbc_clicked()
{
    qDebug()<<"开始收费保存过程\n";

    //清空发票列表
    invoice_list.clear();

    if(ui->pbYbjs->isEnabled() && patientInfo["yb"] == "0")
    {
        QMessageBox:: StandardButton result=
                QMessageBox::warning(this, "注意", "医保挂号患者，确定本次结算不用医保，直接使用现金？",QMessageBox::Yes|QMessageBox::No);

        if(result == QMessageBox::No)
        {
            return;
        }
        qDebug()<<"医保挂号，本次结算不用医保直接使用现金\n";
    }

    //2025-01-09 修改
    if(ui->leYjxj->text().trimmed() != ui->leSf->text().trimmed())
    {
        double sf = ui->leSf->text().trimmed().toDouble();
        double sf45 = QString::asprintf("%.1f", sf).toDouble(); //四舍五入金额

        if( !qFuzzyCompare(sf45, sf) )
        {
            QMessageBox::warning(this, "注意", "录入的现金金额无效！");
            return;
        }
    }
    //2025-01-09 修改 end

    ui->pbSfbc->setEnabled(false);  //开始收费流程，医保预结算和收费按钮禁用。
    ui->pbYbjs->setEnabled(false);  //
    ui->rbX->setChecked(true);      //现金

    qApp->processEvents();  //刷新显示

    if(patientInfo["yb"] == "1" && !busi_2205())
    {
        //使用医保收费，2205交易失败
        return;
    }

    //应缴现金与实缴现金
    double yjxj = ui->leYjxj->text().toDouble();
    double sjxj = ui->leSf->text().toDouble();

    if( qFuzzyCompare(yjxj, sjxj) )
    {
        //实付与应付相等，不需要四舍五入
        balanceFlag = false;
    }
    else
    {
        balanceFlag = true;    //平衡发票间四舍五入余额，非pos机支付现金时需要
        balance = 0;
        balanceSeq = 1;
    }

    //保存收费数据
    qDebug()<<"开始保存收费数据\n";
    ui->lbMode->setText("保存收费数据");
    qApp->processEvents();  //刷新显示


    //int idx;    //索引下标

    if(!calc_store_num()//未通过数量检查
            ||!calc_fee_type()//计算费用分类失败
            )
    {
        return;
    }

    //事务开始
    pub::db_o.transaction();
    QSqlQuery * qr_tmp = new QSqlQuery(pub::db_o);

    if(!calc_invoice(qr_tmp)//保存发票明细
            ||!save_invoice_to_list(qr_tmp)//提取发票明细
            ||!process_SI(qr_tmp)//处理医保相关信息
            ||!process_invo_info(qr_tmp)//处理 fin_opb_invoiceinfo 表相关内容
            ||!save_feedetail(qr_tmp)//写入pha_com_applyout, 补全 fin_opb_feedetail 和 met_ord_recipedetail
            ||!save_recipe(qr_tmp)//保存处方相关内容
            //||true
            )
    {
        //QMessageBox::information(this,"Note","error!");
        pub::db_o.rollback();
        restore_invoice();
        delete qr_tmp;
        return;
    }

    pub::db_o.commit();
    delete qr_tmp;

    //qDebug()<<"lstFeeTypec : "<<lstFeeType<<"\n";
    //qDebug()<<"lstItemDetail : "<<lstItemDetail<<"\n";
    //qDebug()<<"lstInvoiceInfo : "<<lstInvoiceInfo<<"\n";

    ui->lbMode->setText("打印发票");
    qApp->processEvents();  //刷新显示

    on_pbPrint_clicked();
    ui->pbPrint->setEnabled(true);

    if(need_process_5465)
    {
        //push_5465();
        save_5465();
    }

    if(ui->cbAutoFlash->isChecked())
    {
        on_pbSx_clicked();          //
    }
    qDebug()<<"收费保存过程结束\n";
}

